home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Enigma Amiga CD / Programmi / Corso_di_Assembler.lha / lezioni / LEZIONE7.TXT / LEZIONE7.TXT
Text File  |  1994-11-28  |  90KB  |  1,994 lines

  1.  
  2.  CORSO DI ASSEMBLER - LEZIONE 7
  3.  
  4. In questa lezione parleremo degli sprites, del joystick e delle istruzioni
  5. 68000 riguardanti le operazioni sui bit come AND,OR,EOR,NOT,LSR,ROL...
  6.  
  7. Ricordatevi di scrivere "V df0:SORGENTI3" per poter caricare i file .raw
  8. dalla directory dove si trovano i listati di questa lezione.
  9.  
  10. Gli sprite sono oggetti grafici di una dimensione precisa, larghi al massimo
  11. 16 pixel, che si possono muovere per lo schermo indipendentemente dai
  12. bitplanes, per esempio il puntatore a freccia che muovete col mouse per
  13. selezionare dai menu o premere "pulsanti" e' uno sprite gestito dal sistema
  14. operativo, che puo' muoversi dove vuole senza curarsi dei bitplanes che gli
  15. stanno "sotto".
  16. Gli sprite si potrebbero considerare come immagini "fantasma" che si aggirano
  17. "sopra" i bitplanes, ma non tutte le cose che si muovono sono sprites!
  18. Infatti ci possono essere solo 8 sprites al massimo, essendoci sono solo 8
  19. puntatori in copperlist per gli sprites:
  20.  
  21. COPPERLIST:
  22. SpritePointers:
  23.     dc.w    $120,0,$122,0    ; Puntatore per lo Sprite 0
  24.     dc.w    $124,0,$126,0    ; Puntatore per lo Sprite 1
  25.     dc.w    $128,0,$12a,0    ; ""    ""    ""      2
  26.     dc.w    $12c,0,$12e,0    ; ""    ""    ""      3
  27.     dc.w    $130,0,$132,0    ; ""    ""    ""      4
  28.     dc.w    $134,0,$136,0    ; ""    ""    ""      5
  29.     dc.w    $138,0,$13a,0    ; ""    ""    ""      6
  30.     dc.w    $13c,0,$13e,0    ; ""    ""    ""      7
  31.  
  32. I puntatori agli sprite si chiamano registri SPRxPT (al posto della "x" si
  33. mette il numero dello sprite: abbiamo dunque SPR0PT, SPR1PT, .. SPR7PT e
  34. quando parliamo di SPRxPT ci riferiamo in generale a tutti gli 8 puntatori)
  35. Per ora li abbiamo messi nella copperlist azzerati solo per evitare che questi
  36. oggetti "fantasma" saltellino sulle nostre figure senza controllo.
  37. Gli sprite sono isolati dal resto dello schermo, come fossero in una "busta
  38. trasparente" applicata sopra il monitor, infatti la risoluzione degli sprite
  39. e' sempre il lowres, 320x256, anche se i bitplanes sottostanti sono in hires
  40. o interlacciati.
  41. Una verifica che gli sprite non fanno parte dei bitplane e' che per muoverli
  42. non occorre cancellarli e ridisegnarli piu' avanti ogni volta, come avremmo
  43. invece dovuto fare per spostare un pezzo di grafica in un bitplane.
  44. Per muovere uno sprite basta cambiare le sue coordinate agendo con poche e
  45. veloci istruzioni su appositi byte dedicati a questo compito che si trovano
  46. all'inizio della struttura dati dello sprite stesso.
  47. Quando gli sprites non bastano a fare astronavi e ometti in un gioco viene
  48. usato il blitter per copiare blocchi di grafica (bob), che vedremo in seguito.
  49. Come gia' detto, la dimensione di uno sprite e' di 16 pixel di larghezza,
  50. mentre l'altezza puo' essere scelta a piacere, anche tutto lo schermo, cioe'
  51. 256 linee. Per fare un mostro di fine livello si potrebbero usare tutti e 8
  52. gli sprites affiancati, raggiungendo la larghezza totale di 16*8=128 pixel.
  53. Il problema e' che tale mostro sarebbe poco colorato per i tempi che corrono,
  54. infatti uno sprite puo' avere 3 colori al massimo, dato che il "quarto" e' la
  55. parte "trasparente", ossia la parte in cui traspare lo sfondo, ossia i
  56. bitplanes.
  57. La caratteristica degli sprites e' che sono semplici da fare e da animare.
  58. Infatti lo sprite si puo' disegnare con un programma da disegno, basta che
  59. sia largo non piu' di 16 pixel e che abbia 3 colori piu' lo sfondo, ossia 4,
  60. e puo' essere convertito in SPRITE dall'IFFCONVERTER KEFCON.
  61. Oppure si puo' disegnare direttamente in binario, come abbiamo visto per il
  62. font 8x8:
  63.  
  64.          - piano 1 -        - piano 2 -        ; la sovrapposizione di
  65.                             ; questi 2 "piani" di bit
  66.     dc.w    %0111110000000000,%0111110000000000 ; determina il colore.
  67.     dc.w    %1000001000000000,%1111111000000000 ; Questa e' la freccia
  68.     dc.w    %1111010000000000,%1000110000000000 ; putatore di default del
  69.     dc.w    %1111101000000000,%1000011000000000 ; kickstart 1.3, la
  70.     dc.w    %1111110100000000,%1001001100000000 ; riconoscete??
  71.     dc.w    %1110111010000000,%1010100110000000
  72.     dc.w    %0100011101000000,%0100010011000000
  73.     dc.w    %0000001110100000,%0000001001100000
  74.     dc.w    %0000000111100000,%0000000100100000
  75.     dc.w    %0000000011000000,%0000000011000000
  76.     dc.w    %0000000000000000,%0000000000000000
  77.  
  78.     dc.w    0,0    ; Due word azzerate indicano la fine dello sprite.
  79.  
  80. In questo caso la larghezza e' di 16 pixel e non di 8 come nel font 8x8, percui
  81. lo disegnamo in una word (dc.w) e non in un byte.
  82. Inoltre ha 3 colori piu' il trasparente, ossia 4 possibilita' come una figura
  83. a 2 bitplanes, dunque servono un paio di "piani" proprio come per i bitplanes,
  84. e la loro sovrapposizione determinera' il colore, che puo' essere:
  85.  
  86.         Piano 1    - Piano 2
  87.  
  88. binario:     0    -    0    = COLORE 0 (TRASPARENTE)
  89. binario:     1    -    0    = COLORE 1
  90. binario:     0    -    1    = COLORE 2
  91. binario:     1    -    1    = COLORE 3
  92.  
  93. Infatti, come abbiamo gia' visto, con 2 piani di bit si possono formare 4
  94. combinazioni diverse: %00,%01,%10,%11
  95.  
  96. Per decidere la posizione dello sprite basta inserire le coordinate X ed Y
  97. nei primi byte dello sprite stesso. Infatti, prima dei dati del disegno, lo
  98. sprite e' composto da 4 byte, ossia 2 word, dette WORD DI CONTROLLO, ed in
  99. questi byte vanno scritte le coordinate sullo schermo dello sprite.
  100. Per essere piu' esatti, il primo byte, detto VSTART, contiene la posizione
  101. verticale di inizio dello sprite; il secondo byte invece contiene la posizione
  102. orizzontale (HSTART). Il terzo contiene la posizione della fine dello sprite
  103. in senso verticale: per determinarla basta aggiungere l'altezza dello sprite
  104. alla posizione inizio, e come risultato avremo la posizione verticale dove
  105. finisce lo sprite.
  106. Il quarto byte contiene dei bit per funzioni speciali che vederemo.
  107. VSTART e HSTART (Vertical Start e Horizontal Start) dunque sono le coordinate
  108. dell'angolo in alto a sinistra dove inizia lo sprite:
  109.  
  110.  
  111.     #....
  112.     .....
  113.     .....
  114.     .....
  115.     .....
  116.  
  117.  
  118. Mentre VSTOP e' la posizione verticale dove termina lo sprite:
  119.  
  120.  
  121.     .....
  122.     .....
  123.     .....
  124.     .....
  125.     #####    -> linea verticale indicata da VSTOP.
  126.  
  127.  
  128. Per esempio, uno sprite visualizzato alla posizione XX=$90 e YY=$50, lungo 20
  129. pixel, comincerebbe cosi':
  130.  
  131.  
  132.         ;IYIX  FY    - IY=Inizio Y, IX=Inizio X, FY=Fine Y
  133. SPRITE:
  134.     dc.w    $5090,$6400    ;Y=$50, X=$90, altezza= $50+20, cioe' $64
  135. ; da qua iniziano i dati dei 2 piani dello sprite
  136.     dc.w    %0000000000000000,%0000110000110000
  137.     dc.w    %0000000000000000,%0000011001100000
  138.     ...
  139.     dc.w    0,0    ; fine dello sprite
  140.  
  141.  
  142. Infatti il primo byte, VSTART, e' a $50, il secondo, HSTART, e' a $90, mentre
  143. il terzo, la posizione verticale di fine sprite, e' a $64, ossia a $50+20, la
  144. posizione inizio+la lunghezza dello sprite. Il quarto byte per ora lo lasciamo
  145. a zero, vedremo in seguito a cosa serve. Posso premettere che il byte HSTART,
  146. ossia quello che si occupa della posizione orizzontale, fa spostare lo sprite
  147. a "scatti" di 2 pixel alla volta, per cui muovendo uno sprite dalla posizione
  148. $50 alla posizione $51, ad esempio, scatterebbe a destra di 2 pixel, e non di
  149. uno: vedremo che usando un bit del quarto byte si puo' far scorrere lo sprite
  150. di un pixel alla volta orizzontalmente.
  151. Per quanto riguarda la posizione verticale, invece, lo scorrimento avviene gia'
  152. con VSTART/VSTOP a scatti di un pixel, ma la limitazione e' la linea video $FF,
  153. oltre la quale si puo' andare usando un'altro dei bit del quarto byte.
  154. Per ragioni di semplicita' nei primi esempi sposteremo gli sprite solamente
  155. agendo sui byte HSTART, VSTART e VSTOP, ossia con le limitazioni di uno
  156. scorrimento orizzontale a "scatti" di due pixel alla volta.
  157. Solo in un secondo momento vedremo come fare scorrimenti piu' fluidi.
  158. Ricordatevi dunque della particolarita' che, ad esempio, con un
  159.  
  160.     ADDQ.B #1,HSTART
  161.  
  162. spostiamo lo sprite di 2 pixel e non di uno.
  163.  
  164.  
  165. Per agire sui 3 byte VSTART/HSTART/VSTOP si potrebbe fare cosi':
  166.  
  167.     MOVE.B    #$50,SPRITE    ; VSTART = $50
  168.     MOVE.B    #$90,SPRITE+1    ; HSTART = $90
  169.     MOVE.B    #$64,SPRITE+2    ; VSTOP     = $64 ($50+20)
  170.  
  171. Oppure si puo' definire una label per ogni byte per renderlo piu' chiaro:
  172.  
  173.  
  174. SPRITE:
  175. VSTART:            ; posizione inizio VERTICALE
  176.     dc.b $50
  177. HSTART:            ; posizione inizio ORIZZONTALE
  178.     dc.b $90
  179. VSTOP:
  180.     dc.b    $64        ; posizione fine VERTICALE
  181.     dc.b    $00        ; byte per funzioni speciali azzerato
  182.  
  183. ; da qua iniziano i dati dei 2 piani dello sprite
  184.  
  185.     dc.w    %0000000000000000,%0000110000110000
  186.     dc.w    %0000000000000000,%0000011001100000
  187.     ...
  188.     dc.w    0,0    ; fine dello sprite
  189.  
  190.  
  191. In questo caso agiremmo sulle label VSTART,HSTART e VSTOP:
  192.  
  193.     ADDQ.B    #1,HSTART    ; sposta lo sprite a destra di 2 pixel
  194.                 ; (2 pixel e non 1 per le ragioni descritte)
  195.  
  196.     SUBQ.B    #1,HSTART    ; sposta lo sprite a sinistra di 2 pixel
  197.  
  198. Per spostare in basso o in alto lo sprite dovremmo pero' ricordarci di
  199. modificare sia VSTART che VSTOP, perche' e' ovvio che se spostiamo in basso o
  200. in alto lo sprite si sposta sia il primo pixel a sinistra che l'ultimo:
  201.  
  202.     ADDQ.B    #1,VSTART    ; \ sposta lo sprite in basso di 1 pixel
  203.     ADDQ.B    #1,VSTOP    ; /
  204.  
  205.     SUBQ.B    #1,VSTART    ; \ sposta lo sprite in alto di 1 pixel
  206.     SUBQ.B    #1,VSTOP    ; /
  207.  
  208.  
  209. Ricapitolando questa e' la struttura dello sprite:
  210.  
  211.  
  212.     prima word di controllo,     seconda word di controllo
  213.     prima    linea (.w) del piano 1,  prima     linea (.w) del piano 2
  214.     seconda linea (.w) del piano 1,  seconda linea (.w) del piano 2
  215.     terza    linea (.w) del piano 1,  terza     linea (.w) del piano 2
  216.     quarta  linea (.w) del piano 1,  quarta  linea (.w) del piano 2
  217.     quinta  linea (.w) del piano 1,  quinta  linea (.w) del piano 2
  218.     ...
  219.     DC.W    0,0  ; l'ultima riga deve contenere due zeri
  220.  
  221.  
  222. I dati dello sprite sono divisi in piano 1 e piano 2 solo per indicare che la
  223. loro sovrapposizione determina i 3 colori piu' il trasparente in maniera
  224. analoga ai bitplanes dello schermo, ma non vanno confusi con questi ultimi!
  225.  
  226.  
  227. I COLORI DEGLI SPRITE
  228.  
  229. Per definire i colori degli sprite bisogna usare gli stessi registri colore
  230. usati dai bitplanes, in quanto l'Amiga ha solo 32 registri colore.
  231. I progettisti hanno pensato di far assumere agli sprites i colori dal
  232. 16 al 31, per cui se le figure non sono a 32 colori, ossia a 5 bitplanes, gli
  233. sprites possono avere colori diversi dalle figure. Altrimenti gli sprites
  234. avranno 16 colori in comune con la figura a 32 colori sottostante.
  235. Per ora vediamo come definire i colori del primo sprite:
  236.  
  237. (Gli sprite sono numerati dallo 0 al 7)
  238.  
  239.     COLORE 0 dello sprite 0 = TRASPARENZA, non va definito
  240.     COLORE 1 dello sprite 0 = COLOR17 ($dff1a2)
  241.     COLORE 2 dello sprite 0 = COLOR18 ($dff1a4)
  242.     COLORE 3 dello sprite 0 = COLOR19 ($dff1a6)
  243.  
  244. Il colore 0, ossia il quarto, e' la trasparenza e non occorre definirlo.
  245.  
  246. Vediamo, prima di procedere, il primo esempio di visualizzazione di uno sprite
  247. in Lezione7a.s. In questo esempio viene puntato il primo sprite, lasciando
  248. azzerati gli altri 7. Per puntare uno sprite bisogna fare come per i bitplanes,
  249. in quanto lo sprite ha i puntatori che funzionano allo stesso modo:
  250.  
  251.     MOVE.L    #MIOSPRITE,d0        ; indirizzo dello sprite in d0
  252.     LEA    SpritePointers,a1    ; Puntatori in copperlist
  253.     move.w    d0,6(a1)
  254.     swap    d0
  255.     move.w    d0,2(a1)
  256.  
  257. Va ricordato che per visualizzare gli sprite occorre aver "acceso" almeno un
  258. bitplane, con i bitplane disabilitati vengono disabilitati anche gli sprite.
  259. Allo stesso modo, uno sprite viene "tagliato" se va oltre la finestra video,
  260. definita col DIWSTART e DIWSTOP, essendo visualizzabile solo al suo interno.
  261. Da notare che per posizionare nello schermo 320x256 lo sprite, per esempio
  262. alla coordinata centrale 160,128 bisogna tener conto che la prima coordinata in
  263. alto a sinistra, dove inizia la finestra video, non e' 0,0, ma $40,$2c per cui
  264. bisogna sommare $40 alla coordinata X e $2c alla coordinata Y.
  265. Infatti $40+160, $2c+128, corrispondono alla coordinata 160,128 di uno schermo
  266. 320x256 non overscan.
  267. Non avendo ancora il controllo della posizione orizzontale a livello di 1
  268. pixel, ma ogni 2 pixel, dobbiamo sommare non 160, ma 160/2, per individuare il
  269. centro dello schermo:
  270.  
  271.  
  272. HSTART:
  273.     dc.b $40+(160/2)    ; posizionato al centro dello schermo
  274.     ...
  275.  
  276.  
  277. Ecco uno schema dello schermo, in cui la parte visibile, ossia la finestra
  278. video, e' bianca, mentre l'intero schermo, fuori dai bordi, che inizia con
  279. le coordinate 0,0 e' fatto di ####. Si noti che la finestra video comincia
  280. dalle coordinate $40 XX e $2c YY.
  281.  
  282.       (0,0) __
  283.           \
  284.            \
  285.         +---------------------------+
  286.         |###########################|
  287.     /\    |###########################|
  288.     ||    |###+-------------------+###|
  289.     ||    |###| $40,$2c        |###|  __ Bordi dello schermo
  290.     ||    |###|     ______        |###| /   visibile (finestra video)
  291.     ||    |###|    /Sprite\    |###|/
  292.     ||    |###|    |++XX++|    |###/
  293.     ||    |###|    \/\/\/\/    |##/|
  294.         |###|            |#/#|
  295.      ASSE Y    |###|             |/##|
  296.         |###|            |###|
  297.     ||    |###|            |###|
  298.     ||    |###|            |###|
  299.     ||    |###|            |###|
  300.     ||    |###|            |###|
  301.     ||    |###+-------------------+###|
  302.     \/    |###########################|
  303.         |###########################|
  304.         +--------------------------+
  305.             <----- ASSE X ----->
  306.  
  307. La posizione ORIZZONTALE dello sprite puo' andare da 0 a 447, ma e' chiaro
  308. che per essere visibile su schermo largo 320 pixel deve andare da 64 a 383.
  309. La posizione VERTICALE dello sprite invece puo' andare da 0 a 262, ma per 
  310. essere visibile su schermo largo PAL (256 linee) deve andare da 44 ($2c) alla
  311. fine dello schermo,  44+256= 300 ($12c). Per ora abbiamo raggiunto solo la
  312. posizione $FF, vedremo piu' avanti come andare fino alla $12c.
  313.  
  314. In Lezione7b.s lo sprite viene fatto scorrere sullo schermo con degli ADD e SUB
  315. sulle due word di controllo.
  316.  
  317. In Lezione7c.s,  lo sprite viene spostato in orizzontale sullo schermo con
  318. delle tabelle di valori predefiniti anziche' con ADD e SUB.
  319. In Lezione7d.s viene fatto saltellare in verticale.
  320. In Lezione7e.s le due coordinate XX ed YY vengono definite da due tabelle per
  321. creare movimenti circolari, ad ellisse eccetera. In questo esempio viene
  322. anche spiegato come crearsi proprie tabelle!
  323.  
  324. Prima di procedere nella lettura caricate ed eseguite in altri buffer di testo
  325. questi esempi, leggendone i commenti finali.
  326.  
  327. Per ora abbiamo visualizzato un solo sprite, vediamo cosa occorre sapere se
  328. si visualizzano tutti e 8 gli sprite. Innanzitutto ogni sprite ha posizione
  329. indipendente rispetto agli altri, ed ha un VSTART,HSTART e VSTOP propri nelle
  330. prime 2 word. Per quanto riguarda invece i colori (e anche altre proprieta`
  331. degli sprite che vedremo successivamente, come per. es. le collisioni) gli
  332. sprite non sono totalmente indipendenti ma sono accoppiati a due a due. Ci sono
  333. dunque 4 coppie di due sprite: Sprite0+Sprite1, Sprite2+Sprite3,
  334. Sprite4+Sprite5, ed infine Sprite6+Sprite7. In tutto il resto della lezione,
  335. quando parleremo di "coppia di sprite" non intenderemo 2 sprite qualunque, ma
  336. una di queste 4 coppie.
  337. Per i colori, bisogna tenere conto del fatto che gli sprite di una coppia
  338. hanno i colori in comune, ossia ogni coppia di sprite ha la sua
  339. palette (tavolozza) diversa da quella delle altre coppie.
  340. Sappiamo che i 3 colori dello sprite 0 sono definibili coi registri COLOR17,
  341. COLOR18 e COLOR19. Questi 3 colori valgono anche per lo sprite "fratello",
  342. ossia lo sprite 1.
  343. Ogni coppia ha una palette colori diversa perche' sono disponibili i registri
  344. colore dal 16 al 31, ossia 16 registri.
  345. Considerando che ogni sprite ha 4 colori (di cui 1 trasparente), servirebbero
  346. 8*4=32 registri, quando ne sono rimasti solo 16.
  347. Dunque, avendo 8 sprites con 4 colori ciascuno ecco da quali registi le coppie
  348. di sprite prendono i colori:
  349.  
  350.  
  351.         Sprite    Valore binario    Registro di colore:
  352.         ------    --------------    ------------------
  353. Coppia 1:    0 o 1        00    Non Usato perche' trasparente
  354.                 01    Color17 - $dff1a2
  355.                 10    Color18 - $dff1a4
  356.                 11    Color19 - $dff1a6
  357.  
  358. Coppia 2:    2 o 3        00    Non Usato perche' trasparente
  359.                 01    Color21 - $dff1aa
  360.                 10    Color22 - $dff1ac
  361.                 11    Color23 - $dff1ae
  362.  
  363. Coppia 3:    4 o 5        00    Non Usato perche' trasparente
  364.                 01    Color25 - $dff1b2
  365.                 10    Color26 - $dff1b4
  366.                 11    Color27 - $dff1b6
  367.  
  368. Coppia 4:    6 o 7        00    Non Usato perche' trasparente
  369.                 01    Color29 - $dff1ba
  370.                 10    Color30 - $dff1bc
  371.                 11    Color31 - $dff1be
  372.  
  373. Facciamo un esempio pratico: nella copperlist per definire il colore degli 8
  374. sprite e' necessario fare questo:
  375.  
  376.  
  377.     dc.w    $1A2,$F00    ; color17, - COLOR1 degli sprite0/1 -ROSSO
  378.     dc.w    $1A4,$0F0    ; color18, - COLOR2 degli sprite0/1 -VERDE
  379.     dc.w    $1A6,$FF0    ; color19, - COLOR3 degli sprite0/1 -GIALLO
  380.  
  381.     dc.w    $1AA,$FFF    ; color21, - COLOR1 degli sprite2/3 -BIANCO
  382.     dc.w    $1AC,$0BD    ; color22, - COLOR2 degli sprite2/3 -ACQUA
  383.     dc.w    $1AE,$D50    ; color23, - COLOR3 degli sprite2/3 -ARANCIO
  384.  
  385.     dc.w    $1B2,$00F    ; color25, - COLOR1 degli sprite4/5 -BLU
  386.     dc.w    $1B4,$F0F    ; color26, - COLOR2 degli sprite4/5 -VIOLA
  387.     dc.w    $1B6,$BBB    ; color27, - COLOR3 degli sprite4/5 -GRIGIO
  388.  
  389.     dc.w    $1BA,$8E0    ; color29, - COLOR1 degli sprite6/7 -VERDE CH.
  390.     dc.w    $1BC,$a70    ; color30, - COLOR2 degli sprite6/7 -MARRONE
  391.     dc.w    $1BE,$d00    ; color31, - COLOR3 degli sprite6/7 -ROSSO SC.
  392.  
  393. NOTA: Se impostate una figura a 2,4,8 o 16 colori come sottofondo, non ci sono
  394. problemi per la palette, ma se decidete di attivare uno schermo a 32 colori,
  395. ossia 5 bitplanes, la figura avra' in comune gli ultimi colori con gli sprite,
  396. per cui dovete fare in modo che i colori siano giusti sia per la figura che per
  397. lo sprite, che insomma il colore sia "multiuso".
  398.  
  399.  
  400.  
  401. LA PRIORITA' VIDEO TRA GLI SPRITE.
  402.  
  403. Quando ci sono due o piu' sprite sullo schermo puo' avvenire che degli sprite
  404. si sovrappongano. In questo caso viene coperto lo sprite con la priorita'
  405. minore. La priorita' tra gli sprite e' sempre uguale, lo sprite con numero
  406. minore ha sempre priorita' su quelli con numero maggiore, i quali rimangono
  407. "dietro". Di conseguenza lo sprite0 puo' coprire tutti gli altri sprite, mentre
  408. lo sprite 7 puo' essere coperto da tutti gli altri. Ecco uno schemino:
  409.  
  410.                        _______
  411.                       |      |
  412.                        ___|___7   |
  413.                       |          |___|
  414.                     __|___6   |
  415.                    |       |__|
  416.                  __|___5   |
  417.                 |       |__|
  418.                  ___|___4   |
  419.                 |        |___|
  420.                  ___|___3   |
  421.                 |       |___|
  422.              ___|___2   |
  423.             |        |___|
  424.          ___|___1   |
  425.         |    |___|
  426.         |   0   |
  427.         |_______|
  428.  
  429.  
  430. Verifichiamo caricando ed eseguendo in un'altro buffer di testo Lezione7f.s, il
  431. quale visualizza 8 sprite, e dopo la pressione del tasto sinistro del mouse li
  432. sovrappone per evidenziare le priorita'. Tasto destro del mouse per uscire.
  433.  
  434.  
  435. SPRITE "ATTACHED"
  436.  
  437. Esiste anche una modalita' di accoppiamento degli sprite a 2 a 2, l'uno
  438. sull'altro, che riduce il numero degli sprite disponibili alla meta', ossia
  439. a quattro, ma con 16 colori ciascuno anziche' 4.(15 colori piu' il trasparente)
  440. Possono essere combinati solo in questo modo:
  441.  
  442.         SPRITE0+SPRITE1      - Sprite ATTACCHED (attaccato) Numero 1
  443.         SPRITE2+SPRITE3      - Sprite ATTACCHED (attaccato) Numero 2
  444.         SPRITE4+SPRITE5      - Sprite ATTACCHED (attaccato) Numero 3
  445.         SPRITE6+SPRITE7      - Sprite ATTACCHED (attaccato) Numero 4
  446.  
  447. In pratica si attaccano gli sprite che in modalita' normale fanno gia' coppia
  448. perche' hanno la stessa palette. I 4 sprite "attaccati" condividono la stessa
  449. palette di 16 colori, dato che sono disponibili solo i registri colore dal
  450. Color16 al Color31.
  451. Gli sprite ATTACCHED funzionano in questo modo: normalmente uno sprite ha al
  452. massimo 4 possibilita' di sovrapposizione per i suoi piccoli "bitplanes",
  453. ossia %00 per il trasparente e %01,%10,%11 per gli altri 3 colori.
  454. La modalita' ATTACCHED fa sovrapporre i piani di bit dei due sprites per
  455. formare 16 possibilita', infatti ponendo i due piani del primo sopra i 2 piani
  456. del secondo si possono ottenere %1111 possibilita' anziche' %11, ossia 16
  457. anziche' 4.
  458. Nella tabella che segue, nella colonna "valore binario", sono elencate le varie
  459. possibilita' di sovrapposizione e il relativo colore che ne risulta.
  460.  
  461.  
  462.           Colore    Valore     Numero del
  463.           Sprite    binario     registro colore
  464.           -------    ------    --------------
  465.         0    0000    Color16 - NON USATO, E' IL TRASPARENTE
  466.         1    0001    Color17 - $dff1a2
  467.         2    0010    Color18 - $dff1a4
  468.         3    0011    Color19 - $dff1a6
  469.         4    0100    Color20 - $dff1a8
  470.         5    0101    Color21 - $dff1aa
  471.         6    0110    Color22 - $dff1ac
  472.         7    0111    Color23 - $dff1ae
  473.         8    1000    Color24 - $dff1b0
  474.         9    1001    Color25 - $dff1b2
  475.         10    1010    Color26 - $dff1b4
  476.         11    1011    Color27 - $dff1b6
  477.         12    1100    Color28 - $dff1b8
  478.         13    1101    Color29 - $dff1ba
  479.         14    1110    Color30 - $dff1bc
  480.         15    1111    Color31 - $dff1be
  481.  
  482. Dunque in COPPERLIST bisogna definirli in questo modo:
  483.  
  484.     dc.w    $1A2,$F00    ; color17, COLORE 1 per gli sprite attaccati
  485.     dc.w    $1A4,$0F0    ; color18, COLORE 2 per gli sprite attaccati
  486.     dc.w    $1A6,$FF0    ; color19, COLORE 3 per gli sprite attaccati
  487.     dc.w    $1A8,$FF0    ; color20, COLORE 4 per gli sprite attaccati
  488.     dc.w    $1AA,$FFF    ; color21, COLORE 5 per gli sprite attaccati
  489.     dc.w    $1AC,$0BD    ; color22, COLORE 6 per gli sprite attaccati
  490.     dc.w    $1AE,$D50    ; color23, COLORE 7 per gli sprite attaccati
  491.     dc.w    $1B0,$D50    ; color24, COLORE 7 per gli sprite attaccati
  492.     dc.w    $1B2,$00F    ; color25, COLORE 9 per gli sprite attaccati
  493.     dc.w    $1B4,$F0F    ; color26, COLORE 10 per gli sprite attaccati
  494.     dc.w    $1B6,$BBB    ; color27, COLORE 11 per gli sprite attaccati
  495.     dc.w    $1B8,$BBB    ; color28, COLORE 12 per gli sprite attaccati
  496.     dc.w    $1BA,$8E0    ; color29, COLORE 13 per gli sprite attaccati
  497.     dc.w    $1BC,$a70    ; color30, COLORE 14 per gli sprite attaccati
  498.     dc.w    $1BE,$d00    ; color31, COLORE 15 per gli sprite attaccati
  499.  
  500. Per "attaccare" due sprite basta porre ad 1 il bit 7 della seconda word di
  501. controllo dello sprite dispari della coppia (ossia del flamigerato quarto
  502. byte delle funzioni speciali).
  503. Per esempio per attaccare gli sprite 0 ed 1 basta settare tale bit allo
  504. sprite 1, per attaccare lo sprite 4 ed il 5 basta settarlo al 5.
  505. E' ovvio che gli sprite attaccati devono avere le stesse coordinate, ossia
  506. essere l'uno sopra l'altro, per consentire la giusta sovrapposizione dei 4
  507. piani.
  508. Facciamo un esempio: per attaccare gli sprite 0 ed 1 bisogna porre ad 1 il bit
  509. 7 del quarto byte dello sprite1:
  510.  
  511.  
  512. SPRITE0:
  513. VSTART0:        ; posizione inizio VERTICALE
  514.     dc.b $50
  515. HSTART0:        ; posizione inizio ORIZZONTALE
  516.     dc.b $90
  517. VSTOP0:
  518.     dc.b    $64    ; posizione fine VERTICALE
  519.     dc.b    $00    ; non occorre settare il bit 7 agli sprite pari.
  520. ; da qua iniziano i dati dei 2 piani dello sprite
  521.     dc.w    %0000000000000000,%0000110000110000
  522.     dc.w    %0000000000000000,%0000011001100000
  523.     ...
  524.     dc.w    0,0    ; fine sprite0
  525.  
  526.  
  527. SPRITE1:
  528. VSTART1:        ; posizione inizio VERTICALE
  529.     dc.b $50
  530. HSTART:            ; posizione inizio ORIZZONTALE
  531.     dc.b $90
  532. VSTOP:
  533.     dc.b    $64        ; posizione fine VERTICALE
  534.  
  535.         ;76543210
  536.     dc.b    %10000000    ; BIT 7 SETTATO! ATTACCHED MODE per sprite 0/1
  537.  
  538. ; da qua iniziano i dati dei 2 piani dello sprite
  539.     dc.w    %0000000000000000,%0000110000110000
  540.     dc.w    %0000000000000000,%0000011001100000
  541.     ...
  542.     dc.w    0,0    ; fine sprite1
  543.  
  544.  
  545. Dunque per far si' che tutti gli sprite siano in modo "ATTACCHED" basta porre
  546. ad 1 i bit 7 del quarto byte degli sprite 1,3,5 e 7, cioe' di quelli dispari.
  547.  
  548. Per farsi uno sprite a 16 colori e' necessario disegnarlo con un programma da
  549. disegno e convertirlo in formato SPRITE con l'iffconverter KEFCON, infatti e'
  550. difficile "calcolarsi" ad occhio i colori risultanti da 4 piani di bit, divisi
  551. in due sprite!
  552.  
  553. Caricatevi ed eseguitevi il listato Lezione7g.s, che visualizza uno sprite
  554. a 16 colori in modalita' ATTACCHED, in cui e' anche descritto come convertirsi
  555. uno sprite con il KEFCON, sia a 4 colori che a 16.
  556.  
  557. E' possibile visualizzare contemporaneamente sprite a 16 colori e sprite a 4
  558. colori, per esempio gli sprite 0 ed 1 "attaccati" e gli altri no, o qualsiasi
  559. altra combinazione.
  560.  
  561. Nel listato esempio Lezione7h.s sono visualizzati i 4 sprite attacched a 16
  562. colori, ognuno con un movimento indipendente dagli altri.
  563.  
  564. A questo punto vi starete chiedendo come mai non e' ancora stato eliminato
  565. l'inconveniente dello scorrimento orizzontale scattoso a passi di 2 pixel alla
  566. volta anziche' uno. Ebbene, e' giunta l'ora di risolvere il problema, ma per
  567. fare cio' e' necessario imparare una nuova istruzione del 68000, la quale
  568. opera sui singoli bit di un numero:  --- LSR ---
  569. Questa istruzione significa "LOGIC SHIFT RIGHT", cioe' "SCORRIMENTO LOGICO
  570. DEI BIT A DESTRA", in altre parole, se un numero binario in d0 e' %00111, dopo
  571. un bel LSR #1,d0 il risultato e' %00011, dopo un LSR #2,d0 e' %00001.
  572. Allo stesso modo, un %00110010 dopo un LSR #1,d0 diventa %00011001, mentre
  573. dopo un LSR #5,d0 diventa %00000001. Dunque il numero, considerato nella sua
  574. forma binaria, viene spostato a destra come se i bit fossero su una tovaglia
  575. che tiriamo: tirando di #1 si sposta la tovaglia con tutti i BitPiatti sopra
  576. e il primo BitPiatto cade in terra... tirando troppo si puo' spostare tutto
  577. facendo cadere tutto in terra e azzerando il tavolo.
  578. Ma cosa c'entra questa istruzione assembler con il byte HSTART???
  579. Il problema sta in questi termini: come sapete le posizioni orizzontali
  580. possibili sono ben piu' di $FF (255), per il solo fatto che lo schermo e'
  581. largo 320 pixel. Per indicare un numero superiore a 255 (8 bit, dallo zero al
  582. sette), occorre aggiungere almeno un'altro bit, il nono, detto bit 8, in
  583. tal modo anziche' un massimo di %11111111 ($ff) si puo' avere un massimo di
  584. %111111111, ossia 511, che per l'HSTART va benissimo. Ma dove mettere questo
  585. bit?? Quei mattacchioni dei progettisti hanno pensato bene di metterlo nel
  586. famigerato quarto byte di controllo, quello che abbiamo gia' visto per
  587. attaccare gli sprite (il bit 7 di tale byte infatti serve ad attaccare gli
  588. sprite per farli a 16 colori).
  589. Avendo altri 6 bit liberi per usi vari, decisero di usare il bit 0 come bit
  590. BASSO della coordinata a 9 bit della coordinata orizzontale, spezzando il
  591. numero a 9 bit in questo modo:
  592.  
  593.     ;876543210    ; numero a 9 bit, che rappresenta la coordinata HSTART
  594.     %111111111
  595.      \_____/ \/
  596.         |      |
  597.       8 bit alti  |
  598.       messi nel      |
  599.       byte HSTART |
  600.           |
  601.           |
  602.           |
  603.           |
  604.           |
  605.           bit 0 del
  606.           numero a 9 bit
  607.           messo nel bit 0
  608.           del quarto byte
  609.           di controllo
  610.  
  611. Se togliete il bit basso ad un numero a 9 bit, otterrete sempre numeri pari,
  612. dato che il bit 0 e' sempre a zero. E' quando il bit 0 e' ad 1 che il numero
  613. e' dispari, fate una prova con "?100" e "?101", verificherete che i numeri pari
  614. hanno sempre il bit 0 azzerato, mentre quelli dispari hanno sempre il bit 0
  615. settato. Fino ad ora dunque potevamo andare a scatti di 2 pixel per volta e
  616. dovevamo mettere la meta' del valore effettivo in HSTART per questo motivo.
  617. Per poter raggiungere anche i numeri dispari ed inserire la vera coordinata in
  618. input, bastera' dividere tale coordinata reale in bit basso e byte alto, poi
  619. mettere il bit basso al suo posto e il byte alto al suo posto. Per fare cio'
  620. immaginate di avere la coordinata dispari 35: (%00100011)
  621. Quello che dobbiamo fare innanzitutto e' controllare se il bit 0 del quarto
  622. byte di controllo va settato, e per fare questo basta testare se il numero
  623. in questione ha il bit 0 settato con un BTST, dopodiche' si agira' di
  624. conseguenza: supponiamo di avere la coordinata in D0:
  625.  
  626.     btst    #0,D0        ; bit basso della coordinata X azzerato?
  627.     beq.s    BitBassoZERO
  628.     bset    #0,MIOSPRITE+3    ; Settiamo il bit basso di HSTART
  629.     bra.s    PlaceCoords
  630.  
  631. BitBassoZERO:
  632.     bclr    #0,MIOSPRITE+3    ; Azzeriamo il bit basso di HSTART
  633. PlaceCoords:
  634.     ....
  635.  
  636. Ora abbiamo settato o azzerato il bit basso di HSTART, non rimane che mettere
  637. il resto del numero, gli 8 bit piu' alti, nel byte HSTART come sempre.
  638. Ma c'e' un problema: il numero ha 9 bit, e a noi servono solo gli 8 bit alti!
  639. A questo punto compare sulla scena l'istruzione LSR!!! Infatti assolve al
  640. compito di "far scorrere" i bit del numero di una posizione verso destra,
  641. facendo sparire il bit basso e posizionando gli 8 bit che ci servono al punto
  642. giusto, vediamo il seguito della routine sotto la label PlaceCoords:
  643.  
  644.     lsr.w    #1,D0        ; SHIFTIAMO, ossia spostiamo di 1 bit a destra
  645.                 ; il valore di HSTART, per "trasformarlo" nel
  646.                 ; valore fa porre nel byte HSTART, senza cioe'
  647.                 ; il bit basso.
  648.     move.b    D0,HSTART    ; Poniamo il valore XX nel byte HSTART
  649.     rts
  650.  
  651. In questo caso avevamo la coordinata %00100011 (35), vediamo come diventa dopo
  652. l'LSR.W #1,d0: %00010001!!!! Ossia il byte giusto da mettere in HSTART.
  653.  
  654. In Lezione7i.s questa routine viene fatta funzionare per far scorrere uno
  655. sprite FINALMENTE fluido come solo l'Amiga sa fare.
  656.  
  657. A questo punto possiamo eliminare anche l'ultima limitazione, ossia quella in
  658. senso verticale: infatti verticalmente possiamo spostare lo sprite a scatti di
  659. un pixel, ma solo fino alla linea $FF. I progettisti Amiga hanno optato per
  660. una soluzione diversa da quella dell'HSTART per VSTART/VSTOP: infatti anche
  661. VSTART e VSTOP necessitano di un numero a 9 bit anziche' 8, ma anziche'
  662. separare il bit piu' basso (lo zero) dagli altri 8 piu' alti, hanno separato
  663. il bit piu' alto (il nono) dagli otto piu' bassi, in questo modo in VSTART e
  664. VSTOP il numero e' valido fino a $FF, ossia 255, dopodiche' e' necessario
  665. settare il nono bit che e' stato messo nel famigerato quarto byte di
  666. controllo, infatti dopo $ff viene $100,$101 eccetera, dunque il byte basso
  667. riparte da zero, ma col nono bit settato. Vediamo come fare una routine
  668. analoga a quella vista per la posizione orizzontale, ossia che parte dalla
  669. coordinata reale (e' necessaria una word) e la "divide" in bit alto e byte
  670. basso. Da ricordare che in questo caso abbiamo da aggiornare anche VSTOP oltre
  671. a VSTART ogni volta!!! Teniamo presente che il bit alto di VSTOP e' il bit 1
  672. del quarto byte di controllo, mentre quello di VSTART e' il bit 2:
  673.  
  674.     MOVE.w    (A0),d0        ; copia la word dalla tabella in d0
  675.     ADD.W    #$2c,d0        ; aggiungi l'offset dell'inizio dello schermo
  676.     MOVE.b    d0,VSTART    ; copia il byte in VSTART
  677.     btst.l    #8,d0        ; numero maggiore di $FF?
  678.     beq.s    NonVSTARTSET
  679.     bset.b    #2,MIOSPRITE+3    ; Setta il bit 8 di VSTART (numero > $FF)
  680.     bra.s    ToVSTOP
  681. NonVSTARTSET:
  682.     bclr.b    #2,MIOSPRITE+3    ; Azzera il bit 8 di VSTART (numero < $FF)
  683. ToVSTOP:
  684.     ADD.w    #13,D0        ; Aggiungi la lunghezza dello sprite per
  685.                 ; determinare la posizione finale (VSTOP)
  686.     move.b    d0,VSTOP    ; Muovi il valore giusto in VSTOP
  687.     btst.l    #8,d0
  688.     beq.s    NonVSTOPSET
  689.     bset.b    #1,MIOSPRITE+3    ; Setta il bit 8 di VSTOP (numero > $FF)
  690.     bra.w    VstopFIN
  691. NonVSTOPSET:
  692.     bclr.b    #1,MIOSPRITE+3    ; Azzera il bit 8 di VSTOP (numero < $FF)
  693. VstopFIN:
  694.     rts
  695.  
  696. Questa routine funziona in maniera analoga alla precedente per il settaggio
  697. del bit "staccato", mentre si differenzia per il fatto che deve agire sia su
  698. VSTART che su VSTOP, e per l'assenza dell'LSR, qua inutile.
  699.  
  700. Potete provarla in pratica caricando la Lezione7l.s
  701.  
  702. Ora che abbiamo il completo controllo sugli sprite, vediamo di ottimizzare le
  703. routine con le quali li controlliamo: innanzitutto, la prima cosa da fare e'
  704. quella di fare una routine universale di controllo degli sprite, in modo da
  705. non dover riscrivere per ognuno degli 8 sprite la parte della sistemazione
  706. del bit "staccato". Serve una routine parametrica, la quale richieda in
  707. entrata l'indirizzo dello sprite interessato e la coordinata X ed Y che deve
  708. assumere, in questo modo bastera' eseguire un "BSR Routine" per ogni sprite
  709. anziche' riscrivere tutto. Potremo cosi' riutilizzare tale routine ogni volta
  710. che vogliamo programmare gli sprite, al massimo con piccole modifiche. Un
  711. esempio di routine del genere la troviamo nella lezione7m.s.
  712. La routine universale si chiama UniMuoviSprite, e per funzionare e' necessario
  713. che le vengano indicate oltre all'indirizzo dello sprite da muovere e alle
  714. nuove coordinate che deve assumere, anche l'altezza dello sprite, che serve
  715. alla routine per calcolare il valore del byte VSTOP.
  716. Questi valori vengono comunicati o meglio "passati" alla routine mettendoli in
  717. alcuni registri prima di eseguire la routine.
  718. Piu` precisamente si deve mettere l'indirizzo dello sprite nel registro a1,
  719. la sua altezza nel registro d2, la coordinata Y nel registro d0 e la coordinata
  720. X nel registro d1.
  721. La coordinate dello sprite "passate" alla routine sono i valori nello schermo
  722. 320x256. Infatti la routine si occupa di "centrare" lo sprite sullo schermo
  723. sommando $40 alla coordinata X e $2c alla coordinata Y.
  724. Inoltre pensa a mettere a posto il bit basso di HSTART e i bit alti di VSTART
  725. e VSTOP.
  726.  
  727. Brevemente:
  728.  
  729. ;
  730. ;    Parametri in entrata di UniMuoviSprite:
  731. ;
  732. ;    a1 = Indirizzo dello sprite
  733. ;    d0 = posizione verticale Y dello sprite sullo schermo (0-255)
  734. ;    d1 = posizione orizzontale X dello sprite sullo schermo (0-320)
  735. ;    d2 = altezza dello sprite
  736. ;
  737.  
  738. Avendo a disposizione questa routine che ci risolve una volta per tutte i
  739. problemi relativi al posizionamento degli sprite, possiamo divertirci a usarla
  740. per qualche applicazione che ci consentira` di fare un po'di esperienza con 
  741. gli sprite. Prima di proseguire pero' caricate ed eseguite la Lezione7m.s, e
  742. guai a voi se continuate a leggere la lezione7.txt o a caricare listati prima
  743. di averla capita COMPLETAMENTE. Dato che sara' usata in tutti gli altri esempi
  744. sugli sprite, sarebbe poco produttivo continuare senza aver capito una routine
  745. che trovate continuamente.
  746.  
  747.  
  748. Nella lezione7n.s vediamo uno sprite che si muove sullo schermo seguendo
  749. traettorie rettilinee. Le posizioni dello sprite non sono contenute
  750. in un tabella, ma vengono calcolate di volta in volta facendo muovere lo
  751. sprite con velocita` costante. Caricatelo ed eseguitelo, vedremo anche come
  752. far rimbalzare uno sprite contro i bordi dello schermo.
  753.  
  754.  
  755. Nella lezione7o.s vedremo invece due sprite che vengono entrambi mossi dalla
  756. routine universale. E` un ottimo esempio di come grazie all'utilizzo dei
  757. parametri la nostra routine universale sia in grado di muovere senza nessuna
  758. modifica sprite che hanno forma e dimensioni diverse.
  759. Se non usassimo i parametri dovremmo scrivere una routine per ciascun sprite,
  760. sprecando tempo per farlo e memoria sul computer (con 8 sprite dovremmo
  761. scrivere 8 routine).
  762.  
  763.  
  764. Nella lezione7p.s sempre usando la routine universale vediamo come si possano
  765. creare degli oggetti larghi piu` di 16 pixel utilizzando degli sprite
  766. affiancati. State BENE ATTENTI a non confondere gli sprite "ATTACCATI" con
  767. quelli "AFFIANCATI": i primi sono 2 sprite della stessa coppia usati in
  768. modalita` "attached", hanno le stesse coordinate (sono perfettamente
  769. sovrapposti) e lo sprite dispari ha il bit "attach" settato a 1;
  770. per sprite "affiancati" si intende invece un insieme di due o piu` sprite che
  771. vengono posizionati sullo schermo uno di fianco all'altro senza lasciare
  772. neppure una colonna di pixel tra l'uno e l'altro, in maniera da sembrare un
  773. unico oggetto largo piu` di 16 pixel, dato che sono mossi contemporaneamente.
  774. Non c'e` nessun bit da settare per gli sprite affiancati, non si tratta di un
  775. "modo" speciale degli sprite, ma solo di una particolare disposizione sullo
  776. schermo di normalissimi sprite. Ecco uno schemino che mostra un'astronave
  777. fatta da un solo sprite, e un'altra fatta da due sprites:
  778.  
  779.  
  780.      (128,65)             (128,65)        (144,65)
  781.      |_ _ _ __ _ _ _    |_ _ _ _ _ _ __|__ _ _ _ _ _ _
  782.      |     /  \    |    |        /  |  \          |
  783.         __/____\__               /       \
  784.      | |          |    |    |      /    |    \          |
  785.        |          |             ____/___________\____
  786.      | |__________| |    |   |           |      |   |
  787.           \       /            |              |
  788.      |_ _ _\__/_ _ _|    |   |           |      |   |
  789.                     |              |
  790.                 |   |__________|__________|   |
  791.                      \         /
  792.                 |      \    |    /          |
  793.                        \       /
  794.                 |_ _ _ _ _ _\__|__/_ _ _ _ _ _|
  795.  
  796.                    Sprite 0      Sprite 1
  797.  
  798.  
  799. Con una tecnica del genere si possono fare mostri di fine livello larghi fino
  800. a 128 pixel (16*8) se fatti con sprite a 3 colori, oppure larghi fino a 64
  801. pixel (16*4) se fatti con sprite attacched a 15 colori. Se il mostro in
  802. questione e' piu' alto che largo, ad esempio di forma umana, si potrebbe
  803. sfruttare tutta la lunghezza dello schermo, dato che non ci sono limiti per
  804. l'altezza di uno sprite, e si potrebbe cambiare la palette verticalmente col
  805. copper per colorargli, ad esempio, le scarpe con un colore diverso dai jeans.
  806.  
  807.  
  808. MOUSE E JOYSTICK
  809.  
  810. Ora che abbiamo visto come far muovere gli sprite all'Amiga, perche` non
  811. impariamo muoverli noi? Naturalmente con l'aiuto di un joystick o di un mouse!
  812.  
  813. Prima di vedere come si usano questi dispositivi e` necessario imparare delle
  814. nuove istruzioni assembler, che riguardano la manipolazione dei bit di un
  815. registro e che si chiamano NOT, AND, OR, EOR.
  816. Queste istruzioni lavorano sui singoli bit di un registro (o di una locazione
  817. di memoria), sia per il registro sorgente che per quello destinazione.
  818. Ad esempio queste istruzioni considerano un byte non come un numero formato
  819. da 8 bit (cifre binarie) ma come un insieme di 8 bit indipendenti tra di
  820. loro. In pratica questo vuol dire che l'effetto che l'istruzione ha su un
  821. singolo bit del registro e` indipendente da quello che succede agli altri bit
  822. del registro.
  823.  
  824. Per prima vediamo la NOT. Essa funziona su un solo operando, e il suo effetto
  825. e` quello di rovesciare i bit dell'operando, cioe` di scambiare 1 con 0 e 0
  826. con 1. Se ad esempio nel registro d0 abbiamo il numero %01001100, se facciamo
  827.         NOT.B   d0
  828. il risultato sara` %10110011.
  829.  
  830. Le altre 3 istruzioni, invece lavorano con 2 operandi, uno sorgente e l'altro 
  831. destinazione, fanno un'operazione tra i contenuti degli operandi e mettono il
  832. risultato nell'operando destinazione. Le operazioni (che sono ovviamente
  833. diverse per ogni istruzione) sono bit-a-bit, cioe` avvengono tra ogni bit
  834. dell'operando sorgente e il corrispondente bit dell'operando destinazione,
  835. nel quale inoltre viene poi messo il risultato. Quindi fare D0 AND D1
  836. in pratica significa fare:
  837. (bit 0 di D0) AND (bit 0 di D1)
  838. (bit 1 di D0) AND (bit 1 di D1)
  839. (bit 2 di D0) AND (bit 2 di D1) e cosi` via per tutti i bit di D0 e D1
  840.  
  841. Vediamo dunque come funziona l'AND tra 2 bit. Poiche` un bit vale 0 o 1,
  842. ci sono 4 possibili casi:
  843.  
  844.  0 AND 0 = 0
  845.  0 AND 1 = 0
  846.  1 AND 0 = 0
  847.  1 AND 1 = 1
  848.  
  849. AND da come risultato 1 soltanto quando sia il bit del primo operando
  850. che quello del secondo operando sono ad 1. Infatti AND in inglese significa
  851. "e" , quindi da come risultato 1 se il primo E il secondo bit sono a 1.
  852. Si potrebbe tradurre con:
  853. "SONO AD 1 SIA IL PRIMO CHE IL SECONDO BIT? SE SI, RISPONDO CON 1, SE NO
  854. INVECE RISPONDO CON UNO ZERO".
  855. Un AND puo' essere utile ad azzerare certi bit di un numero:
  856.  
  857.  AND.W #%1111111111111011,LABEL
  858.  
  859. Azzerera' il bit 2 del numero in LABEL, perche' e' l'unico che e' azzerato
  860. nell'operando, e l'unico che sara' cambiato nella destinazione, infatti
  861. tutti gli altri sono ad 1, quindi questi non cambiano la destinazione.
  862. Se il bit di destinazione e' 0, facendo un 1 AND 0 il risultato rimane 0,
  863. allo stesso modo se e' 1, facendo un 1 AND 1 il risultato rimane 1. Per quanto
  864. riguarda il bit che e' a 0, invece, condanna la destinazione ad essere 0,
  865. infatti per dare un 1 di destinazione entrambi gli operandi devono essere 1,
  866. in questo caso essendo a 0 il primo, sia che il secondo sia 0 o 1 il risultato
  867. sara' 0. alcuni esempi:
  868.  
  869.    1111001111 AND 0011001100 = 0011001100 - Nessuna modifica
  870.    1101011011 AND 0001110001 = 0001010001 - 1 bit azzerato
  871.    1111101101 AND 0011111111 = 0011101101 - 2 bit azzerati
  872.  
  873. Questa operazione di azzeramento si dice MASCHERATURA:
  874.  
  875.  AND #%11110000,LABEL    (%11110000 e' la maschera, infatti e' come se si
  876.             mettesse una maschera di ZERI sopra il numero
  877.             in LABEL, in questo caso e' come se "tappassimo"
  878.             i primi 4 bit come si "tappa" un neo una ragazza
  879.             quando si mette il fondotinta. Il neo e' un 1 che
  880.             si trovava nella posizione della maschera dove
  881.             c'erano degli 0, e il neo che viene "coperto"
  882.             dal trucco, ossia viene azzerato).
  883.  
  884. L'OR invece si comporta in questo modo:
  885.  
  886.  0 OR 0 = 0
  887.  0 OR 1 = 1
  888.  1 OR 0 = 1
  889.  1 OR 1 = 1
  890.  
  891. In questo caso basta che 1 dei 2 bit sia ad 1 per dare risultato 1.
  892. Dunque il risultato e' sempre 1 tranne quando entrambi i bit sono a zero.
  893. Anche qui sapere che OR in inglese significa "o" ci aiuta a ricordare che
  894. il risultato e` 1 se il primo O il secondo bit sono a 1.
  895. Si potrebbe tradurre in "O UNO O L'ALTRO BIT DEVONO ESSERE AD 1 PER DARE 1"
  896. Questo comando e' utile, all'opposto dell'AND, per SETTARE dei bit, per porli
  897. cioe' ad 1: alcuni esempi:
  898.  
  899.     0000000001 OR 1101011101 = 1101010001 - Nessun cambiamento
  900.     1000000000 OR 0010011000 = 1010011000 - 1 bit settato
  901.     0001111000 OR 1111100000 = 1111111000 - 2 bit settati
  902.  
  903. In questo caso, e' come se la ragazza di prima, anziche' mettersi il
  904. fondotinta rosaceo (gli 0) per tappare i nei neri (ossia gli 1), si mettesse
  905. del nero per farsi dei nei falsi, come quello che aveva Marilin Monroe sopra
  906. il labbro. Oppure come se fosse una ragazza di colore (ossia tutta ad 1) che
  907. si e' truccata con il rosa per sembrare bianca (come Michael Jackson), ossia
  908. per essere tutta a zero, che si toglie il fondotinta dove il numero dell'OR
  909. e' ad uno, scoprendo il nero.
  910.  
  911. Invece il comando EOR, ovvero OR esclusivo, setta il bit solo quando e' ad 1
  912. o il primo o il secondo bit, non quando sono ad 1 entrambi, come invece fa
  913. il comando or:
  914.  
  915.  0 EOR 0 = 0
  916.  0 EOR 1 = 1
  917.  1 EOR 0 = 1
  918.  1 EOR 1 = 0         ; Questa e' la differenza con l'OR! infatti 1 OR 1 = 1.
  919.  
  920. Alcuni esempi:
  921.     0000000001 EOR 1101011101 = 1101010000 - 1 bit azzerato
  922.     1000000000 EOR 0010011000 = 1010011000 - 1 bit settato
  923.  
  924. Quest'ultima istruzione ci sara` utile per leggere il joystick.
  925.  
  926. Come sapete l'Amiga ha 2 porte usate per collegare joystick o mouse. Ad
  927. ognuna di queste porte si puo` collegare indifferentemente un joystick o un
  928. mouse. Per ogni porta esiste un registro hardware che si puo` leggere per
  929. sapere se e in che modo sono mossi joystick e mouse. La porta 0 (dove di
  930. solito e` collegato il mouse) viene letta attraverso il registro JOY0DAT
  931. ($dff00a) mentre la porta 1 attraverso JOY1DAT ($dff00c).
  932. Per prima cosa vediamo come leggere il joystick. Ci riferiremo al registro
  933. JOY1DAT che e` quello usato di solito, ma JOY0DAT funziona esattamente allo
  934. stesso modo quando ci colleghiamo un joystick.
  935. Possiamo pensare ad un joystick come ad un insieme di 4 interruttori (uno per
  936. ogni direzione), ognuno dei quali puo` assumere 2 stati:  chiuso (1) o
  937. aperto (0) a seconda che la leva del joystick sia premuta o meno nella
  938. direzione associata all'interruttore. Per sapere in quali direzioni e` mosso
  939. il joystick dobbiamo conoscere gli stati degli interruttori.
  940. Per 2 di questi interruttori e` molto semplice, in quanto il loro stato e`
  941. riportato in un bit del registro JOY1DAT:
  942. - il bit 1 di JOY1DAT e` lo stato dell'interruttore "destra"
  943. - il bit 9 di JOY1DAT e` lo stato dell'interruttore "sinistra".
  944. Se un bit vale 1 l'interruttore associato e` chiuso, altrimenti e` aperto.
  945. Per quanto riguarda le altre 2 direzioni lo stato non e` mappato direttamente
  946. in un bit, ma deve essere ottenuto mediante il calcolo di un'operazione,
  947. precisamente dell'EOR che abbiamo spiegato poco fa, effettuata tra 2 bit del
  948. registro JOY1DAT:
  949. - lo stato dell'interruttore "alto" e` il risultato di un EOR tra
  950.   il bit 8 e il bit 9
  951. - lo stato dell'interruttore "basso" e` il risultato di un EOR tra
  952.   il bit 0 e il bit 1.
  953. Anche in questo caso se un bit vale 1 l'interruttore associato e` chiuso,
  954. altrimenti e` aperto.
  955. Conoscendo gli stati dei 4 interruttori possiamo dunque usare il joystick per
  956. muovere uno sprite sullo schermo.
  957.  
  958. Caricate in un altro buffer di testo la lezione7q.s ed eseguitela
  959.  
  960. Veniamo ora al mouse. Quando colleghiamo un mouse ad una delle porte, il
  961. registro corrispondente si comporta in maniera diversa che nel caso del
  962. joystick. Infatti prendendo il registro JOY0DAT (ma e` lo stesso per l'1),
  963. troviamo che il byte alto e` usato per rilevare gli spostamenti in direzione
  964. verticale e quello basso quelli in direzione orizzontale. Ogni byte
  965. rappresenta un numero (da 0 a 255) che varia secondo i movimenti del mouse.
  966. - il byte alto diminuisce ogni volta che il mouse viene spostato verso l'alto
  967.   e aumenta ogni volta che il mouse viene spostato verso il basso.
  968. - il byte basso diminuisce ogni volta che il mouse viene spostato verso
  969.   sinistra e aumenta ogni volta che il mouse viene spostato verso destra.
  970. Vediamo come usare queste informazioni per muovere uno sprite con il mouse.
  971. Il primo metodo che viene in mente e` di usare i 2 byte di JOY0DAT come
  972. coordinate per lo sprite, visto che anche le coordinate dello sprite
  973. diminuiscono se esso va in alto o a sinistra e aumentano se va in basso o a
  974. destra.
  975. Questo metodo ha l'inconveniente che in un byte possiamo raggiungere il
  976. valore 255, quindi i valori che possiamo leggere dal byte di JOY0DAT dedicato
  977. alla direzione orizzontale possono arrivare al massimo a 255, mentre le
  978. coordinate orizzontali di uno sprite possono arrivare oltre 320.
  979.  
  980. Caricate Lezione7r1.s e verificate questo metodo.
  981.  
  982. Un metodo un po' piu` complesso che pero` risolve il problema della
  983. limitazione in senso orizzontale a 255 pixel anziche' 320 e` presentato in
  984. Lezione7r2.s. Per una spiegazione del metodo leggetevi il commento alla fine
  985. del listato.
  986.  
  987. Sapendo come muovere una freccia sullo schermo, si puo' facilmente simulare
  988. il sistema intuition, ossia si puo' fare un pannello di controllo con dei
  989. bottoni disegnati da attivare spostandoci la freccia (lo sprite) sopra e
  990. premendo il pulsante, sia esso del joystick o del mouse. Basta controllare al
  991. momento della pressione del bottone in quale coordinata si trova la freccia,
  992. e se si trova sopra un bottone attivare l'opzione di quel bottone.
  993. Fare questo e' piuttosto facile, provate da voi a farlo. Comunque in lezioni
  994. piu' avanzate del corso ci sara' un listato di questo tipo.
  995.  
  996.  
  997.  
  998. RIUTILIZZO DEGLI SPRITE
  999.  
  1000. Il riutilizzo degli sprite e` una tecnica che ci consente di visualizzare
  1001. piu` di 8 sprite contemporaneamente. In pratica uno stesso sprite viene usato
  1002. per disegnare diversi oggetti situati a diverse altezze.
  1003. Se ad esempio utilizziamo uno sprite per visualizzare un alieno nella parte
  1004. alta dello schermo, possiamo poi utilizzare di nuovo lo stesso sprite per
  1005. disegnare l'astronave del giocatore nella parte bassa dello schermo.
  1006. L'unica limitazione che si ha quando si riutilizzano gli sprite e` che 2
  1007. oggetti disegnati da uno stesso sprite devono essere posizionati ad altezze
  1008. differenti. Non e` possibile visualizzare su una stessa riga dello schermo 2
  1009. righe che compongono 2 oggetti disegnati con il medesimo sprite.  Per di piu`
  1010. l'ultima riga della figura disegnata durante un utilizzo e la prima riga
  1011. della figura disegnata con l'utilizzo successivo dello stesso sprite DEVONO
  1012. essere separate da almeno una riga nella quale lo sprite non e` utilizzato.
  1013. La figura seguente illustra meglio la situazione:
  1014.  
  1015.         porzione di schermo
  1016.      ________________________
  1017.     |             |      Ogni immagine in questa porzione
  1018.     |          _     |      di schermo e` disegnata dal
  1019.     |        _|_|_     |      medesimo sprite.
  1020.     |        \___/ _ _|_ _      Ogni immagine puo` essere
  1021.     |     _ _ _ _ _ _ _ _ _ _|_ _ <-- posizionata liberamente
  1022.     |   _/_\_         |      orizzontalmente.
  1023.     |  |_____|         |      Pero`, almeno una riga di schermo
  1024.     |    \_/_ _ _ _ _ _ _ _ _|_ _      deve separare l'ultima riga
  1025.     |        _ _ _ _ _ _ _|_ _ <-- di un utilizzo dello sprite dalla
  1026.     |       /\         |      prima riga dell'utilizzo
  1027.     |       \/         |      successivo.
  1028.     |             |
  1029.     |             |
  1030.     |________________________|
  1031.  
  1032.  
  1033. Non c'e` nessuna limitazione invece per quanto riguarda le posizioni
  1034. orizzontali, né per quanto riguarda figure disegnate mediante sprites diversi.
  1035. Uno sprite puo` essere riutilizzato un numero qualunque di volte, ogni volta
  1036. ad un'altezza diversa.
  1037. Questa tecnica si puo` applicare ad ogni sprite, e in modo indipendente tra
  1038. uno sprite e l'altro: per esempio si possono utilizzare 1 volta sola gli sprite
  1039. 0,3 e 4, utilizzare 3 volte lo sprite 1, quattro volte lo sprite 2 e non
  1040. utilizzare affatto gli sprite 5,6 e 7.
  1041.  
  1042. Applicare questa tecnica e` molto semplice, in quanto richiede solo una
  1043. modifica della struttura dati dello sprite.
  1044.  
  1045. Normalmente, alla fine della struttura dello sprite, dopo tutti i dati che
  1046. descrivono la forma ci sono 2 word di valore 0 che appunto indicano la fine
  1047. della struttura. Per riutilizzare uno sprite, al posto di queste 2 word ci
  1048. mettiamo un'altra struttura sprite, che descrive un'altra figura da disegnare
  1049. sullo schermo piu` in basso della prima. Se si vuole riutilizzare per una
  1050. terza volta lo sprite, si mette una terza struttura sprite subito dopo la
  1051. seconda, e lo stesso si fa per tutti i riutilizzi che si vuole. Dopo la
  1052. struttura dati dell'ultimo utilizzo si mettono le 2 word di valore 0 che
  1053. indicano la fine dell'ultimo utilizzo.
  1054.  
  1055.  
  1056.           STRUTTURA SPRITE
  1057.       ___________________________ - -
  1058.       |  |     VSTART_1, HSTART_1    |   |
  1059.      |___________________________|
  1060.       |  |     VSTOP_1 e bits         |   |
  1061.      |___________________________|
  1062.       |                       |
  1063.       ___________________________
  1064.       |  |     piano 1, riga 1       |   |
  1065.      |___________________________|
  1066.       |  |     piano 2, riga 1       |   |
  1067.      |___________________________|         Dati del primo
  1068.       |                       |- - - utilizzo dello
  1069.         ------                sprite
  1070.       |        ------             |
  1071.         ------
  1072.       |   ___________________________    |
  1073.      |  piano 1, ultima riga     |
  1074.       |  |___________________________|   |
  1075.      |  piano 2, ultima riga     |
  1076.       |  |___________________________|   |
  1077.                       - -
  1078.       ___________________________ - -
  1079.       |  |    VSTART_2, HSTART_2     |   |    Dati del secondo
  1080.      |___________________________|        utilizzo dello sprite
  1081.       |  |    VSTOP_2 e bit         |   |- - - La posizione di inizio
  1082.      |___________________________|        verticale deve essere
  1083.       |                     |    almeno una riga piu` in
  1084.       ___________________________        basso dell'ultima riga
  1085.       |  |                 |     |    del precedente utilizzo.
  1086.      |___________________________|
  1087.       |  |                 |     |
  1088.      |___________________________|
  1089.       |                     |
  1090.         ------
  1091.       |        ------             |
  1092.         ------
  1093.       |   ___________________________     |
  1094.      |                 |
  1095.       |  |___________________________|     |
  1096.      |                 |
  1097.      \|/ |___________________________|     |
  1098.                       - -
  1099.                       _ _
  1100.         _____             |
  1101.         _____             |- - -    Utilizzi successivi
  1102.         _____              _ _|
  1103.  
  1104.       ___________________________ _ _
  1105.      |         0             |     |    Due word azzerate
  1106.            |___________________________|     |_ _ _ che indicano la fine
  1107.      |         0             |     |    dell'ultimo utilizzo
  1108.           |___________________________|_ _|
  1109.  
  1110.  
  1111. Da notare che i vari utilizzi verticali devono essere messi nella struttura
  1112. in ordine da quello piu` in alto a quello piu` in basso.
  1113. Per cui il byte VSTART di ogni utilizzo deve essere MAGGIORE del byte VSTOP
  1114. dell'utilizzo precedente dello sprite.
  1115.  
  1116. Vediamo un esempio pratico di struttura in cui uno sprite e` riutilizzato
  1117. 2 volte:
  1118.  
  1119. MIOSPRITE:
  1120. VSTART_1:
  1121.     dc.b $50                ; posizione primo utilizzo
  1122. HSTART_1:
  1123.     dc.b $40+12
  1124. VSTOP_1:
  1125.     dc.b $58
  1126.     dc.b $00
  1127.  dc.w    %0000001111000000,%0111110000111110    ; dati "forma" del primo
  1128.  dc.w    %0000111111110000,%1111001110001111    ; utilizzo
  1129.  dc.w    %0011111111111100,%1100010001000011
  1130.  dc.w    %0111111111111110,%1000010001000001
  1131.  dc.w    %0111111111111110,%1000010001000001
  1132.  dc.w    %0011111111111100,%1100010001000011
  1133.  dc.w    %0000111111110000,%1111001110001111
  1134.  dc.w    %0000001111000000,%0111110000111110
  1135. VSTART_2:                                ; posizione utilizzo 2
  1136.     dc.b $70            ; NOTATE CHE VSTART_2 > VSTOP_1
  1137. HSTART_2:
  1138.     dc.b $40+20
  1139. VSTOP_2:
  1140.     dc.b $78
  1141.     dc.b $00
  1142.  dc.w    %0000001111000000,%0111110000111110    ; dati "forma" del
  1143.  dc.w    %0000111111110000,%1111001110001111    ; secondo utilizzo
  1144.  dc.w    %0011111111111100,%1100010001000011
  1145.  dc.w    %0111111111111110,%1000001110000001
  1146.  dc.w    %0111111111111110,%1000010001000001
  1147.  dc.w    %0011111111111100,%1100010001000011
  1148.  dc.w    %0000111111110000,%1111001110001111
  1149.  dc.w    %0000001111000000,%0111110000111110
  1150.  dc.w    0,0                    ; fine ultimo utilizzo
  1151.  
  1152.  
  1153. La tecnica del riutilizzo, se
  1154. ben sfruttata, puo' portare a moltiplicare gli oggetti in movimento in uno
  1155. shoot'em'up. Ad esempio in un gioco a scrolling orizzontale, dove i nemici
  1156. si muovono orizzontalmente:
  1157.  
  1158.  
  1159.             /--___
  1160.             \--
  1161.     
  1162.                 /--___
  1163.                 \--
  1164.     
  1165.                     /--___
  1166.        ()-                \--
  1167.        /\___o - - - - - -
  1168.       ||||--o - - - - - -            /--___
  1169.       ||||                    \--
  1170.       //\\
  1171.      //  \\
  1172. ------------------------------------------------------------
  1173.  
  1174. La formazione nemica, essendo formata da oggetti che si spostano in senso
  1175. per lo piu' orizzontale, senza mai andare l'uno sopra l'altro, puo' essere
  1176. fatta da un solo sprite riutilizzato. In questo modo avremmo altri 7 sprite
  1177. per il player1 e per le eventuali bombe.
  1178.  
  1179.  
  1180. Un esempio di utilizzo di questa tecnica lo potete trovare in lezione7s.s dove
  1181. visualizzeremo "16" sprite contemporaneamente. Caricatelo e studiatevelo.
  1182.  
  1183.  
  1184. Non poteva poi mancare nel nostro corso, uno degli effetti piu` "classici"
  1185. delle intro di qualche anno fa: lo "starfield", ovvero le stelle che si muovono
  1186. orizzontalmente.
  1187. Le stelle infatti sono realizzate usando uno sprite riutilizzato.
  1188. Ne presentiamo 3 versioni in lezione7t1.s, lezione7t2.s e lezione7t3.s.
  1189. Il riutilizzo degli sprite si puo` applicare anche agli sprite "attaccati",
  1190. allo stesso modo degli sprite normali. In lezione7t4.s vediamo un esempio nel
  1191. quale realiziamo un effetto simile allo "starfield" ma con palline colorate al
  1192. posto delle stelle.
  1193.  
  1194.     -        -        -        -
  1195.  
  1196. IL DUAL PLAYFIELD MODE
  1197.  
  1198. Prima di spiegare altre caratteristiche degli sprite, faremo una digressione
  1199. per approfondire la trattazione del Dual Playfield mode.
  1200. Come abbiamo gia` accennato nella lezione 4, il Dual Playfield e` un modo
  1201. grafico speciale che consente di visualizzare due schermi sovrapposti,
  1202. chiamati PLAYFIELD 1 e 2. Cosa vuol dire che i 2 schermi sono sovrapposti?
  1203. In pratica ogni playfield, ha un colore "trasparente" attraverso il quale si
  1204. puo` vedere quello che c'e` sotto, esattamente allo stesso modo del colore 0
  1205. di ogni sprite. In pratica il trasparente non e` un vero colore ma
  1206. una sorta di "buco" all'interno del playfield. Gli altri colori di ogni
  1207. playfield si comportano invece normalmente. Uno dei due PLAYFIELD (a scelta)
  1208. appare al di sopra dell'altro, e i suoi colori NON trasparenti ricoprono
  1209. l'altro playfield; il trasparente, invece si comporta come un buco e lascia
  1210. vedere il playfield sottostante.
  1211. Il numero massimo di bit-planes che ognuno dei 2 playfield puo` avere
  1212. e` 3 bit-plane in LOW-RES e 2 bit-plane in HI-RES. In pratica i 6
  1213. bit-planes dell'Amiga vengono ripartiti in due gruppi da 3, e ogni gruppo
  1214. costituisce un playfield. Il playfield 1 e` costituito dai bit-plane dispari,
  1215. cioe` i bit-plane 1, 3 e 5. Il playfield 2 e` costituito dai bit-plane pari,
  1216. cioe` 2, 4 e 6.
  1217. Naturalmente non e` sempre necessario usare tutti i bit-plane disponibili. Non
  1218. possiamo pero` assegnare indipendentemente ai 2 playfield i bit-plane che
  1219. vogliamo. Infatti il numero di bit-planes da usare si indica esattamente nello
  1220. stesso modo che per i modi grafici "normali". Nei bit 14-12 del registro
  1221. BPLCON0 ($dff100), chiamati bit BPU2, BPU1 e BPU0 viene indicato il numero
  1222. complessivo di bit-plane da attivare nei 2 playfield. In base al numero
  1223. complessivo che noi indichiamo nei bit BPU, l'hardware assegna i bit plane
  1224. secondo la seguente tabella:
  1225.  
  1226.  
  1227. Numero di bitplanes usati   |    Bit-planes al      |    Bit-planes al
  1228.  (bit BPU di BPLCON0)        |    Playfield 1      |    Playfield 2
  1229. ----------------------------|---------------------|-------------------
  1230.                 |              |
  1231.     0            |    nessuno      |    nessuno
  1232.                 |              |
  1233.     1            |    plane 1      |    nessuno
  1234.                 |              |
  1235.     2            |    plane 1      |    plane 2
  1236.                 |              |
  1237.     3            |    plane 1,3      |    plane 2
  1238.                 |              |
  1239.     4            |    plane 1,3      |    plane 2,4
  1240.                 |              |
  1241.     5            |    plane 1,3,5      |    plane 2,4
  1242.                 |              |
  1243.     6            |    plane 1,3,5      |    plane 2,4,6
  1244.  
  1245.  
  1246. Come potete vedere in pratica il playfield 1 ha sempre piu` planes del
  1247. playfield 2, ed inoltre, il playfield 2 ha al massimo un plane in meno del
  1248. playfield 1; non e` possibile assegnare 3 plane al playfield 1 e un solo
  1249. plane al playfield 2.
  1250.  
  1251. Analogamente ai modi grafici standard, la sovrapposizione dei bit-plane
  1252. determina il colore usato per rappresentare ogni pixel sul video.
  1253. Pero` la corrispondenza tra combinazioni dei bit-plane e registri colore e`
  1254. un po' differente, ed illustrata nelle 2 tabelle seguenti:
  1255.  
  1256. PLAYFIELD 1
  1257.   Valore    | Valore        | Valore    |  Colore
  1258.     plane 5    |    plane 3    |    plane 1    |  selezionato
  1259. ----------------------------------------------------
  1260.         |        |        |
  1261.     0    |    0    |    0    |  trasparente
  1262.         |        |        |
  1263.     0    |    0    |    1    |  COLOR01
  1264.         |        |        |
  1265.     0    |    1    |    0    |  COLOR02
  1266.         |        |        |
  1267.     0    |    1    |    1    |  COLOR03
  1268.         |        |        |
  1269.     1    |    0    |    0    |  COLOR04
  1270.         |        |        |
  1271.     1    |    0    |    1    |  COLOR05
  1272.         |        |        |
  1273.     1    |    1    |    0    |  COLOR06
  1274.         |        |        |
  1275.     1    |    1    |    1    |  COLOR07
  1276.  
  1277.  
  1278. PLAYFIELD 2
  1279.   Valore    |  Valore    |  Valore    |  Colore
  1280.     plane 6    |    plane 4    |    plane 2    |  selezionato
  1281. ----------------------------------------------------
  1282.         |        |        |
  1283.     0    |    0    |    0    | trasparente
  1284.         |        |        |
  1285.     0    |    0    |    1    |  COLOR09
  1286.         |        |        |
  1287.     0    |    1    |    0    |  COLOR10
  1288.         |        |        |
  1289.     0    |    1    |    1    |  COLOR11
  1290.         |        |        |
  1291.     1    |    0    |    0    |  COLOR12
  1292.         |        |        |
  1293.     1    |    0    |    1    |  COLOR13
  1294.         |        |        |
  1295.     1    |    1    |    0    |  COLOR14
  1296.         |        |        |
  1297.     1    |    1    |    1    |  COLOR15
  1298.  
  1299.  
  1300. A questo punto sapete come funziona il Dual Playfield mode. C'e` solo unica
  1301. cosa che non sapete... come si attiva il dual playfield !!
  1302. E` molto semplice basta settare a 1 il bit 10 del registro BPLCON0.
  1303. Come abbiamo gia` detto e` possibile scegliere quale dei due playfield appaia 
  1304. al di sopra dell'altro. Si dice che il playfield che appare sopra ha priorita`
  1305. maggiore. C'e` un bit che determina la priorita`, il bit 6 del registro
  1306. BPLCON2 ($dff104): se esso vale 0 il playfield 1 appare sopra al 2, se invece
  1307. vale 1 e` il playfield 2 che appare sopra all'1.
  1308.  
  1309. Potete vedere un esempio di Dual Playfield in lezione7u.s
  1310.  
  1311.  
  1312. PRIORITA` TRA SPRITE E PLAYFIELD
  1313.  
  1314. Abbiamo gia` visto le priorita` relative dei vari sprite. Cioe` se due sprite
  1315. si sovrappongono, quello con il numero piu` basso apparira` al di sopra
  1316. dell'altro. Inoltre abbiamo appena visto come stabilire la priorita` tra i 2
  1317. playfield nel modo Dual Playfield. Non ci resta ora che vedere le priorita`
  1318. tra sprite e playfield. Innanzitutto notiamo che gli sprite appaiono sempre
  1319. al di sopra del colore zero. Per gli altri colori la priorita` e` controllata
  1320. dal registro BPLCON2. E` possibile settare la priorita` indipendentemente per
  1321. i bit-planes pari e per i dispari. Cio` e` molto utile nel modo Dual
  1322. Playfield, perche` ci consente di dare ad ogni playfied una diversa priorita` 
  1323. rispetto agli sprite. Nel modo standard, invece e` opportuno dare la stessa 
  1324. priorita` rispetto agli sprite a planes pari e dispari. Il registro BPLCON2
  1325. possiede alcuni bit nei quali scrivere il livello di priorita` desiderato per
  1326. planes pari e dispari. I bit da 0 a 2 contengono il livello di priorita`
  1327. dei bit-planes dispari (che corrispondono al PLAYFIELD 1 nel modo Dual
  1328. Playfield) mentre i bit da 3 a 5 contengono il livello di priorita`
  1329. dei bit-planes pari (PLAYFIELD 2 nel modo Dual Playfield).
  1330. Vediamo come e` codificato il livello di priorita`, riferendoci ad un
  1331. generico playfield, visto che la codifica e` identica nei 2 casi.
  1332. Per quanto riguarda le priorita` con i playfield gli sprite si considerano a 
  1333. coppie (0-1, 2-3, 4-5 e 6-7). Come sappiamo, la priorita` tra gli sprite
  1334. (e quindi tra le coppie) e` fissa:
  1335.  
  1336. PRIORITA` MASSIMA       COPPIA 1 (SPRITES 0 E 1)
  1337.                         COPPIA 2 (SPRITES 2 E 3)
  1338.                         COPPIA 3 (SPRITES 4 E 5)
  1339. PRIORITA` MINIMA        COPPIA 4 (SPRITES 6 E 7)
  1340.  
  1341. Il livello di priorita` ci permette di inserire in questa pila il nostro
  1342. playfield: lo possiamo mettere al di sopra di tutte le coppie, al di sotto di
  1343. tutte le coppie, o in mezzo a 2 coppie. Non e` quindi possibile far comparire
  1344. il playfield al di sotto della coppia 4 e al di sopra della coppia 2, perche`
  1345. la coppia 2 si trova piu` in alto della coppia 4 nella pila. E` invece
  1346. possibile il contrario. Mostriamo ora una tabella con tutte le possibili
  1347. priorita`, a seconda del livello che settiamo nei bit di BPLCON2
  1348.  
  1349. CODICE    |    000    |    001    |    010    |    011    |    100    |
  1350. ----------------------------------------------------------------------------
  1351. PRI. MAX  | PLAYFIELD | COPPIA 1  | COPPIA 1  | COPPIA 1  | COPPIA 1  |
  1352.           | COPPIA 1  | PLAYFIELD | COPPIA 2  | COPPIA 2  | COPPIA 2  |
  1353.           | COPPIA 2  | COPPIA 2  | PLAYFIELD | COPPIA 3  | COPPIA 3  |
  1354.           | COPPIA 3  | COPPIA 3  | COPPIA 3  | PLAYFIELD | COPPIA 4  |
  1355. PRI. MIN  | COPPIA 4  | COPPIA 4  | COPPIA 4  | COPPIA 4  | PLAYFIELD |
  1356.  
  1357. Per esempio, come si vede dalla tabella, se vogliamo che gli sprite 0,1,2,3
  1358. (cioe` le coppie 1 e 2) appaiano al di sopra del playfield e gli altri sprite
  1359. invece al di sotto, dobbiamo scegliere il codice %010. Questo codice
  1360. andra` scritto nel registro BPLCON2, nei bit da 0 a 2 se ci si riferisce al
  1361. playfield 1 in dual-playfield, nei bit da 3 a 5 se ci si riferisce al
  1362. playfield 2 in dual-playfield, mentre se stiamo usando uno schermo normale,lo 
  1363. dovremo scrivere 2 volte, sia nei bit da 0 a 2 che nei bit da 3 a 5.
  1364.  
  1365. In lezione7v1.s trovate un esempio di come settare le priorita` degli sprite
  1366. con uno schermo "normale".
  1367.  
  1368. In lezione7v2.s invece, viene usato uno schermo Dual Playfield.
  1369.  
  1370.  
  1371.  
  1372. COLLISIONI
  1373.  
  1374. L'hardware di Amiga mette a disposizione del programmatore un sistema di
  1375. rilevamento delle collisioni tra sprite e sprite, di quelle tra sprite e
  1376. playfield e di quelle tra i 2 playfield.
  1377. Tutti questi tipi di collisione vengono gestiti mediante 2 soli registri:
  1378. CLXDAT ($dff00e) che e` un registro a sola lettura nel quale vengono
  1379. segnalate le collisioni, e CLXCON ($dff098), che e` un registro di controllo
  1380. mediante il quale si puo` modificare il modo in cui le collisioni vengono
  1381. rilevate. Cominciamo illustrando la struttura di questi registri.
  1382. I bit del registro CLXDAT si comportano come dei rilevatori di collisione.
  1383. Ogni bit e` dedicato ad un particolare tipo di collisione. Quando si
  1384. verifica una collisione di un determinato tipo, il bit ad essa dedicato in
  1385. CLXDAT assume il valore 1. Quando la collisione non si verifica piu` il bit
  1386. ritorna al valore 0. Nella seguente tabella illustriamo il significato dei
  1387. bit di CLXDAT:
  1388.  
  1389. USO DEI BIT DI CLXDAT
  1390.  
  1391. bit 15  non usato
  1392. bit 14  collisione tra coppia 3 e coppia 4
  1393. bit 13  collisione tra coppia 2 e coppia 4
  1394. bit 12  collisione tra coppia 2 e coppia 3
  1395. bit 11  collisione tra coppia 1 e coppia 4
  1396. bit 10  collisione tra coppia 1 e coppia 3
  1397. bit 9  collisione tra coppia 1 e coppia 2
  1398. bit 8  collisione tra playfield 2 e coppia 4
  1399. bit 7  collisione tra playfield 2 e coppia 3
  1400. bit 6  collisione tra playfield 2 e coppia 2
  1401. bit 5  collisione tra playfield 2 e coppia 1
  1402. bit 4  collisione tra playfield 1 e coppia 4
  1403. bit 3  collisione tra playfield 1 e coppia 3
  1404. bit 2  collisione tra playfield 1 e coppia 2
  1405. bit 1  collisione tra playfield 1 e coppia 1
  1406. bit 0  collisione tra playfield 1 e playfield 2
  1407.  
  1408. Il registro CLXCON ha la seguente struttura
  1409.  
  1410. USO BIT DI CLXCON
  1411. bit 15  abilita sprite 7
  1412. bit 14  abilita sprite 5
  1413. bit 13  abilita sprite 3
  1414. bit 12  abilita sprite 1
  1415. bit 11  abilita bit-plane 6
  1416. bit 10  abilita bit-plane 5
  1417. bit 9  abilita bit-plane 4
  1418. bit 8  abilita bit-plane 3
  1419. bit 7  abilita bit-plane 2
  1420. bit 6  abilita bit-plane 1
  1421. bit 5  valore-collisione bit-plane 6
  1422. bit 4  valore-collisione bit-plane 5
  1423. bit 3  valore-collisione bit-plane 4
  1424. bit 2  valore-collisione bit-plane 3
  1425. bit 1  valore-collisione bit-plane 2
  1426. bit 0  valore-collisione bit-plane 1
  1427.  
  1428. (nota: dove e` scritto "abilita" si intende ABILITA PER IL RILEVAMENTO
  1429. COLLISIONI: se per esempio il bit 15 di CLXCON vale 0 NON vuol dire che lo
  1430. sprite 7 non puo apparire sullo schermo, ma solo che le collisioni che
  1431. riguardano lo sprite 7 non vengono rilevate)
  1432.  
  1433. Spiegheremo un po' alla volta il significato di questi bit.
  1434. Cominciamo a parlare della collisione tra sprite e sprite.
  1435. Diciamo subito che anche per quanto riguarda le collisioni gli sprite
  1436. sono considerati al livello di coppie.
  1437. Infatti e` possibile rilevare solo le collisioni tra sprite appartenenti a
  1438. coppie diverse, e non fra sprite appartenenti alla stessa coppia.
  1439. Per esempio non e` possibile rilevare la collisione di sprite 0 con sprite 1.
  1440. Invece vengono rilevate collisioni tra sprite appartenenti a coppie diverse.
  1441. Per esempio se si verifica una collisione tra sprite 0 e sprite 2 il bit 9 di
  1442. CLXDAT (collisione tra coppia 1 e coppia 2) assume il valore 1. Se si
  1443. verifica una collisione tra sprite 1 e sprite 2, poiche` anche lo sprite 1
  1444. appartiene (come lo 0) alla coppia 1, sara` sempre il bit 9 ad assumere il
  1445. valore 1. Questo pero` non accadra` sempre.
  1446. Infatti le collisioni che riguardano gli sprite di numero pari (cioe` gli
  1447. sprite 0,2,4 e 6) vengono sempre rilevate, ma le collisioni che riguardano gli
  1448. sprite dispari, vengono rilevate solo se noi vogliamo. Per abilitare
  1449. uno sprite dispari al rilevamento collisioni, dobbiamo mettere a 1 il
  1450. corrispondente bit di abilitazione nel registro CLXCON. Potete vedere quali
  1451. sono i bit nella tabella che abbiamo riportato sopra. Gli sprite dispari
  1452. possono essere abilitati indipendentemente l'uno dall'altro. Abilitare uno
  1453. o piu` sprite dispari al rilevamento delle collisioni, comporta vantaggi e
  1454. svantaggi. Consideriamo per esempio solo le coppie 1 e 2, e supponiamo
  1455. di non aver abilitato ne` lo sprite 1 ne` lo sprite 3. In questo caso,
  1456. se si verifica una collisione tra sprite 0 e 2, il bit 9 (di CLXDAT)
  1457. assume valore 1. Se invece la collisione si verifica tra sprite 1 e 2,
  1458. oppure tra 0 e 3, oppure tra 1 e 3, non accade nulla, e noi non possiamo
  1459. sapere che la collisione e` avvenuta.
  1460. Supponiamo invece di aver abilitato uno degli sprite dispari, per esempio
  1461. sprite 1. In questo caso le collisioni tra sprite 0 e 2 e tra sprite 1 e 2
  1462. pongono a 1 il bit 9 di CLXDAT, mentre le collisioni tra sprite 0 e 3 e tra
  1463. sprite 2 e 3 non provocano nessun effetto. In questa situazione c'e` uno
  1464. svantaggio rispetto al caso precedente, in cui lo sprite 1 non era abilitato.
  1465. Infatti nel caso precedente, se il bit 9 assumeva il valore 1 eravamo sicuri
  1466. che la collisione era avvenuta tra sprite 0 e sprite 2. Nel caso presente
  1467. invece ci sono 2 possibilita`: o c'e` collisione tra sprite 0 e 2 oppure tra
  1468. sprite 1 e 2. Non vi e` modo di risolvere l'enigma leggendo il registro
  1469. CLXDAT.
  1470. Se lo sprite 1 e` disabilitato, ma lo sprite 3 e` abilitato, si ha una
  1471. situazione analoga, in quanto vengono rilevate le collisioni tra sprite 0 e 2
  1472. e tra sprite 0 e 3, ma non si riesce a distinguere quale delle 2 si e`
  1473. verificata.
  1474. Infine nel caso in cui sono abilitati sia lo sprite 1 che il 3, vengono
  1475. rilevate collisioni tra sprite 0 e 2, tra sprite 0 e 3, tra sprite 1 e 2 e
  1476. tra sprite 1 e 3, e non c'e` modo di distinguere.
  1477.  
  1478.  
  1479. Un esempio di collisione tra sprite, con gli sprite dispari disabilitati al
  1480. rilevamento collisioni, e` in lezione7w1.s. Caricatelo e verificatene il
  1481. funzionamento.
  1482.  
  1483.  
  1484. Un esempio di collisione tra sprite con uno sprite dispari abilitato e` nella
  1485. lezione7w2.s. Noterete che questo esempio cosi` com'e` non funziona; per farlo
  1486. funzionare, dovrete seguire le modifiche indicate nel commento.
  1487. In questo esempio, per distinguere se una collisione riguarda lo sprite dispari
  1488. abilitato, o lo sprite pari ad esso accoppiato, viene impiegata una tecnica
  1489. basata sul confronto delle posizioni, illustrata nel commento.
  1490.  
  1491.  
  1492. Veniamo ora alla collisione tra sprite e playfield.
  1493. E` possibile rilevare una collisione tra una coppia di sprite e uno o piu`
  1494. colori del playfield. Anche in questo caso le collisioni sono rivelate
  1495. considerando coppie di sprite e non i singoli membri della coppia.
  1496. L'abilitazione degli sprite dispari tramite i bit del registro CLXCON ha
  1497. effetto anche in questo caso.
  1498. Il rilevamento delle collisioni avviene in modo diverso se stiamo usando uno
  1499. schermo normale o Dual Playfield. Con uno schermo normale, i bit da 1 a 4
  1500. di CLXDAT indicano una collisione tra una coppia di sprite e il colore (o i
  1501. colori) che abbiamo scelto per la collisione. Il bit 1 indica collisione tra
  1502. il playfield e la coppia 1, il bit 2 tra playfield e coppia 2, il bit 3 tra
  1503. playfield e coppia 3, il bit 4 tra playfield e coppia 4. I bit da 5 a 8
  1504. invece non vanno usati.
  1505. Nel caso di modo dual playfield e` possibile rilevare una collisione tra uno
  1506. dei 2 playfield e una coppia di sprite, e i bit di CLXDAT si usano come
  1507. indicato nella tabella del registro CLXDAT: i bit da 1 a 4 indicano le
  1508. collisioni tra playfield 1 e le varie coppie di sprite, mentre i bit da 5 a 8
  1509. indicano le collisioni tra playfield 2 e le varie coppie di sprite.
  1510. Per scegliere i colori con cui rilevare le collisioni si usa il registro
  1511. CLXCON. Iniziamo con il caso di un solo colore.
  1512. I bit da 6 a 11 di CLXCON indicano quali bit-planes sono attivi
  1513. per le collisioni. Nel caso in cui vogliamo rilevare collisioni tra sprite e
  1514. un solo colore dobbiamo abilitare per le collisioni tutti i bit-planes che
  1515. vengono visualizzati. La scelta del colore con cui rilevare una collisione
  1516. viene effettuata scrivendo il numero del registro in cui e` contenuto il
  1517. colore nei bit da 0 a 5 di CLXCON.
  1518. Per esempio supponiamo di avere uno schermo normale a 16 colori (4 bit-planes)
  1519. e di non voler considerare le collisioni degli sprite dispari.
  1520. Se vogliamo rilevare una collisione tra uno sprite e il colore 13 dobbiamo
  1521. scrivere nel registro CLXCON il valore
  1522.  
  1523.         111111
  1524.         5432109876543210
  1525.  $03cb=%0000001111001101
  1526.  
  1527. Guardiamo il significato dei bit. I bit da 12 a 15 disabilitano gli sprite
  1528. dispari. Dei bit da 6 a 11 sono a 1 solo i bit 6,7,8,9. Questo indica che
  1529. solo i bit-planes da 1 a 4 sono abilitati per le collisioni. Si tratta dei
  1530. soli bit-planes attivi. I bit da 0 a 5 contengono il numero %001101=13 cioe`
  1531. il numero del registro che ci interessa. Nel caso Dual Playfield la
  1532. situazione e` la stessa, solo che attivando tutti i bit-planes utilizzati per
  1533. le collisioni si abilitano le collisioni con 2 colori contemporaneamente:
  1534. per esempio, se con 2 playfield da 8 colori ciascuno vogliamo abilitare il
  1535. rilevamento delle collisioni per il colore 7 del playfield 1 e il colore 2
  1536. del playfield 2 dobbiamo scrivere in CLXCON il numero
  1537.  
  1538.         111111
  1539.         5432109876543210
  1540.  $0fbb=%0000111111011101
  1541.  
  1542. Questa combinazione di bit indica che tutti i bit-planes sono abilitati al
  1543. rilevamento collisioni (tutti i bit da 6 a 11 valgono 1).
  1544. Inoltre il numero del colore usato per il playfield 1 e` dato dai bit
  1545. 0,2 e 4 che messi affiancati formano il numero %111=7, mentre il numero del
  1546. colore usato per il playfield 2 e` dato dai bit 1,3 e 5 che messi affiancati
  1547. formano il numero %010=2.
  1548. Da notare che la collisione di uno sprite con un colore del playfield 1
  1549. provoca l'accensione di un bit di CLXDAT diverso dal caso di collisione dello
  1550. stesso sprite con un colore del playfield 2. Per esempio, come potete
  1551. verificare nella tabella del registro CLXDAT, la collisione sprite 0 -
  1552. playfield 1 mette a 1 il bit 1 di CLXDAT, mentre la collisione sprite 0 -
  1553. playfield 2 mette a 1 il bit 5 di CLXDAT.
  1554.  
  1555. E` possibile anche rilevare collisioni di uno sprite con piu` di un colore
  1556. contemporaneamente sebbene solo in alcune particolari condizioni.
  1557. Per capire come cio` sia possibile occorre tenere presente la rappresentazione
  1558. binaria dei numeri dei registri colore.
  1559. Ci sono, come sapete 32 registri colore numerati da 0 a 31.
  1560. La possibilita` di rilevare collisioni con 2 colori contemporaneamente si basa
  1561. sul fatto che le rappresentazioni di alcuni numeri binari sono simili.
  1562. Per esempio consideriamo i numeri 2 e 21.
  1563. In binario si ha 2=%00010 e 21=%10101 (consideriamo 5 bit per poter scrivere
  1564. numeri fino a 31).
  1565. Come vedete le rappresentazioni binarie di questi 2 numeri sono completamente
  1566. diverse.
  1567. Non vi e` modo dunque di rilevare collisioni con entrambi i colori
  1568. contemporaneamente.
  1569. Consideriamo invece i numeri 22 e 23.
  1570. Osserviamo ora che espressi in binario 22=%010110 e 23=%010111.
  1571. Le rappresentazioni dei 2 numeri differiscono solo per un bit, il bit piu`
  1572. basso. In questo caso e` possibile rilevare collisioni con entrambi i colori.
  1573. Infatti il valore del bit piu` basso (che in questo caso differenzia i colori)
  1574. e` dato dal bit-plane 1.
  1575. Se noi NON abilitiamo il bit-plane 1 al rilevamento collisioni, verranno presi
  1576. in considerazione solo i valori dei bit-plane 2,3,4 e 5 (siamo su uno schermo
  1577. a 32 colori, quindi in totale 5 bit-planes), e il valore assunto dal
  1578. bit-plane 1 non avra` alcuna influenza. Scriviamo dunque in CLXCON il valore:
  1579.  
  1580.          111111
  1581.          5432109876543210
  1582. CLXCON= %0000011110010110
  1583.  
  1584. Questo vuol dire che la collisione verra` rilevata basandosi sui soli
  1585. bit-plane abilitati (e cioe` 2,3,4 e 5) e precisamente quando il nostro
  1586. sprite si sovrapporra` ad un pixel che abbia:
  1587.  
  1588. bitplane 1=(0 o 1) perche` non e` abilitato
  1589. bitplane 2=1
  1590. bitplane 3=1
  1591. bitplane 4=0
  1592. bitplane 5=1
  1593.  
  1594. Come abbiamo visto, sia la rappresentazione binaria di 22=%010010
  1595. che quella di 23=%010111 hanno questa particolare configurazione di bit,
  1596. pertanto entrambi i colori provocano una collisione al passaggio dello
  1597. sprite. Notate che il bitplane che NON abbiamo abilitato (l'1) corrisponde
  1598. proprio all'unico bit che differenzia le rappresentazioni binarie di 22 e di
  1599. 23.
  1600. Questa tecnica e` applicabile a una qualunque coppia di colori le cui
  1601. rappresentazioni binarie differiscano di un solo bit. Per esempio anche i
  1602. numeri 8=%001000 e 9=%001001 differiscono per il bit piu` basso, quindi anche
  1603. per rilevare collisioni tra lo sprite e questi 2 colori si deve disabilitare
  1604. il bit-plane 1. Se invece consideriamo i colori 10=%001010 e 14=%001110,
  1605. notiamo che le 2 rappresentazioni binarie differiscono nel bit 2 (numeriamo i
  1606. bit da destra a sinistra a partire da 0) che corrisponde al bit-plane 3.
  1607. Per rilevare collisioni tra lo sprite e questi 2 colori si deve disabilitare
  1608. il bit-plane 3, e pertanto assegnare a CLXCON il valore riportato sotto:
  1609.  
  1610.          111111
  1611.          5432109876543210
  1612. CLXCON= %0000011011001010   ; bit 8=0 indica bit-plane 3 NON abilitato
  1613.  
  1614. Se disabilitiamo 2 bit-plane possiamo rilevare collisioni tra 4 colori.
  1615. Il principio e` sempre lo stesso. Prendiamo per esempio i colori:
  1616.  
  1617. 1=%00001
  1618. 3=%00011
  1619. 5=%00101
  1620. 7=%00111
  1621.  
  1622. questi 4 colori hanno i bit 0, 3 e 4 uguali tra loro, mentre si differenziano
  1623. in quanto ogni colore ha una diversa combinazione di valori nei bit 1 e 2.
  1624. Per rilevare collisioni tra uno sprite e tutti e 4 questi colori basta
  1625. disabilitare i bit-plane 2 e 3 che corrispondono appunto ai bit 1 e 2.
  1626. Disabilitando 3 bit plane si rilevano collisioni con 8 colori
  1627. contemporaneamente, disabilitandone 4 con 16 colori.
  1628. Anche operando in modo Dual Playfield e` possibile, per ciascun playfield,
  1629. disabilitare alcuni bit-planes per rilevare collisioni tra lo sprite e 
  1630. piu` di un colore per ogni playfield (ricordiamo che se dobbiamo rilevare la
  1631. collisione tra lo sprite e 2 colori che pero` appartengono uno al playfield 1
  1632. e uno al playfield 2 cio` non e` necessario, perche` in CLXDAT abbiamo per
  1633. ogni playfield un bit che ci consente di rilevare contemporaneamente la
  1634. collisione con entrambi i playfield).
  1635.  
  1636.  
  1637. In lezione7x1.s vediamo un esempio di collisione tra sprite e
  1638. playfield in modo "standard".
  1639.  
  1640.  
  1641. In lezione7x2.s invece c'e` un esempio con il modo Dual Playfield.
  1642. In entrambi i listati nel commento sono riportati diversi esempi di come
  1643. rilevare collisioni con piu` di un colore per volta.
  1644.  
  1645.  
  1646. L'ultimo tipo di collisione e` tra playfield 1 e playfield 2, ovviamente in
  1647. modo Dual Playfield. E` possibile rilevare una collisione tra uno o
  1648. piu` colori del playfield 1 e uno o piu` colori del playfield 2, abilitando
  1649. solo alcuni bit-planes esattamente con la stessa procedura adottata nel caso 
  1650. di collisione tra sprite e playfield.
  1651. Quando viene rilevata una collisione tra i due playfield, bit 0 di CLXDAT
  1652. assume il valore 1.
  1653.  
  1654.  
  1655. Un esempio di questo tipo di collisione e` in lezione7x3.s
  1656.  
  1657.  
  1658.  
  1659. USO DIRETTO DEI REGISTRI DEGLI SPRITE
  1660.  
  1661. Vedremo ora un diverso metodo per utilizzare gli sprite. Finora abbiamo
  1662. generato degli sprite utilizzando i registri SPRxPT, ovvero dei puntatori a
  1663. delle strutture dati (dette strutture sprite) che contengono tutte le
  1664. informazioni necessarie alla visualizzazione degli sprite. Esiste pero` un
  1665. altro metodo per creare degli sprite che puo` essere usato in alternativa o
  1666. anche in aggiunta a quello con i puntatori. Chiameremo questo nuovo metodo
  1667. "uso diretto degli sprite". L'uso diretto degli sprite non e` conveniente
  1668. nella maggior parte dei casi, ma a volte puo` risultare utile.
  1669. Per comprendere bene di cosa si tratti dobbiamo approfondire il discorso sulla
  1670. visualizzazione degli sprite.
  1671. Quando memorizziamo in un registro SPRxPT l'indirizzo di una struttura
  1672. sprite (secondo le modalita` della tecnica "standard" di utilizzo degli 
  1673. sprite), attiviamo una procedura automatica che permette di visualizzare
  1674. effettivamente gli sprite. Infatti i dati sulla posizione e la forma che noi
  1675. abbiamo memorizzato nella struttura sprite, vengono trasferiti
  1676. automaticamente, attraverso un "meccanismo" hardware chiamato DMA, in
  1677. appositi registri, diversi dai registri SPRxPT; e` proprio la scrittura dei
  1678. dai in questi registri che REALMENTE permette la visualizzazione degli
  1679. sprite. Del DMA, che e` uno strumento molto importante dell'Amiga, diremo di
  1680. piu` in una prossima lezione. Per il momento ci basta conoscere il ruolo che
  1681. esso svolge nella visualizzazione degli sprite. Si comporta in pratica come
  1682. un postino. Immaginate che la struttura dati dello sprite che voi avete
  1683. costruito in memoria sia un mucchio di lettere indirizzate a diversi
  1684. destinatari (registri). Il DMA si occupa di portare queste lettere a
  1685. destinazione, smistandole tra i vari destinatari.
  1686. L'uso diretto degli sprite consiste, appunto, nello scrivere direttamente
  1687. i dati degli sprite negli appositi registri, cioe` nel portare "di persona"
  1688. le lettere ai vari destinatari, rubando il lavoro al postino DMA. Visto che
  1689. il DMA svolge il suo lavoro gratis, vi potreste chiedere a cosa serva questa
  1690. tecnica. In effetti come abbiamo gia` detto di solito essa non offre
  1691. vantaggi; tuttavia in alcuni casi puo` rivelarsi utile.
  1692. Vediamo dunque in cosa consiste questa tecnica. Come abbiamo gia` detto i dati
  1693. degli sprite vengono scritti direttamente in alcuni registri. Ci sono 4
  1694. registri per ogni sprite, chiamati SPRxPOS, SPRxCTL, SPRxDATA, SPRxDATB (al
  1695. posto della x dovete mettere il numero dello sprite che volete usare.)
  1696. Gli indirizzi di questi registri dipendono dallo sprite a cui ci si
  1697. riferisce. Li possiamo calcolare con delle semplici formule. Con "x"
  1698. indichiamo il numero dello sprite, da 0 a 7.
  1699.  
  1700. indirizzo SPRxPOS  = $dff140+(x*8)
  1701. indirizzo SPRxCTL  = $dff142+(x*8)
  1702. indirizzo SPRxDATA = $dff144+(x*8)
  1703. indirizzo SPRxDATB = $dff146+(x*8)
  1704.  
  1705. Potete comunque cercarli con l'help dell'ASMONE "=C".
  1706.  
  1707. Ora descriviamo l'uso di questi registri. La forma di uno sprite viene
  1708. scritta nei registri SPRxDATA e SPRxDATB, che costituiscono i 2 piccoli 
  1709. bit-planes dello sprite (SPRxDATB e` il piano 2). Questi registri hanno lo
  1710. stesso ruolo delle coppie di word che definiscono la forma di una riga dello
  1711. sprite nella struttura sprite. Notate che per ogni sprite ci sono 2 registri
  1712. che contengono i dati relativi ad UNA SOLA riga dello sprite. La posizione
  1713. orizzontale di uno sprite come sapete e` costituita da 9 bit, chiamati H0, H1 
  1714. .. H8. Questi 9 bit sono suddivisi in due registri: il bit H0, cioe` il bit
  1715. basso si trova nel bit 0 del registro SPRxCTL. Gli altri 8 invece nel byte
  1716. basso del registro SPRxPOS. In poche parole questi 2 registri si comportano,
  1717. per quanto riguarda la posizione orizzontale, esattamente come le 2 word di
  1718. controllo della struttura sprite. La posizione verticale, invece, con questa
  1719. tecnica non viene determinata, perche' gli sprite si comportano in modo
  1720. piuttosto strano.
  1721. Per essere visualizzato, uno sprite deve essere attivato.
  1722. Cio` accade quando si scrive nel registro SPRxDATA.
  1723. Una volta attivato, lo sprite viene visualizzato ad ogni riga nella posizione
  1724. orizzontale indicata, come abbiamo appena visto, nei registri SPRxPOS e
  1725. SPRxCTL. La forma dello sprite e` per ogni riga quella contenuta nei registri
  1726. SPRxDATA e SPRxDATB.
  1727. Quindi se il contenuto di questi registri non viene modificato ad ogni riga,
  1728. lo sprite avra` la stessa forma ad ogni riga.
  1729. Lo sprite viene visualizzato, fino a che non lo si disattiva scrivendo nel
  1730. registro SPRxCTL.
  1731. Per visualizzare uno sprite che cambi forma ad ogni riga si dovrebbe dunque
  1732. utilizzare una copperlist fatta in questa maniera:
  1733. (supponiamo di usare lo sprite 0 e che sia VSTART=$40, VSTOP=$60, HSTART=$160)
  1734.  
  1735.  
  1736.     dc.w    $4007,$fffe    ; WAIT - aspetta la linea VSTART
  1737.     dc.w    $140,$0080    ; SPR0POS - posizione orizzontale
  1738.     dc.w    $142,$0000    ; SPR0CTL
  1739.     dc.w    $146,$0e70    ; SPR0DATB - forma sprite riga 1, piano 2
  1740.     dc.w    $144,$03c0    ; SPR0DATA - forma sprite riga 1, piano 1
  1741.                                 ; inoltre attiva la visualizzazione, per
  1742.                                 ; questo va scritta per ultima.
  1743.  
  1744.     dc.w    $4107,$fffe    ; WAIT - aspetta la linea VSTART+1
  1745.     dc.w    $146,$0a70    ; SPR0DATB - forma sprite riga 2, piano 2
  1746.     dc.w    $144,$0300    ; SPR0DATA - forma sprite riga 2, piano 1
  1747.  
  1748.     dc.w    $4107,$fffe    ; WAIT - aspetta la linea VSTART+2
  1749.     dc.w    $146,$0a7f    ; SPR0DATB - forma sprite riga 3, piano 2
  1750.     dc.w    $144,$030f    ; SPR0DATA - forma sprite riga 3, piano 1
  1751.  
  1752. ; ripeti per ogni riga Y
  1753. ;    dc.w    $40+Y07,$fffe    ; WAIT - aspetta la linea VSTART+Y
  1754. ;    dc.w    $146,DATOY2    ; SPR0DATB - forma sprite riga Y, piano 2
  1755. ;    dc.w    $144,DATOY1    ; SPR0DATA - forma sprite riga Y, piano 1
  1756. ; mettendo al posto di DATOY1 e DATOY2 i dati della forma degli sprite.
  1757.  
  1758.     dc.w    $6007,$fffe    ; WAIT - aspetta la linea VSTOP
  1759.     dc.w    $142,$0000    ; SPR0CTL - disattiva lo sprite
  1760.  
  1761. Come vedete per sprite abbastanza alti e` necessaria una copperlist molto
  1762. lunga e complicata. In questo caso conviene decisamente usare il DMA.
  1763. Supponiamo pero` di dover visualizzare uno sprite che abbia la stessa forma
  1764. ad ogni riga. Per esempio uno sprite che rappresenti una colonna. In questa
  1765. situazione la nostra copperlist diventa semplicissima e cortissima:
  1766.  
  1767. (supponiamo di usare lo sprite 0 e che sia VSTART=$40, VSTOP=$60, HSTART=$160)
  1768.  
  1769.  
  1770.     dc.w    $4007,$fffe    ; WAIT - aspetta la linea VSTART
  1771.     dc.w    $140,$0080    ; SPR0POS - posizione orizzontale
  1772.     dc.w    $142,$0000    ; SPR0CTL
  1773.     dc.w    $146,$0e70    ; SPR0DATB - forma sprite riga 1, piano 2
  1774.     dc.w    $144,$03c0    ; SPR0DATA - forma sprite riga 1, piano 1
  1775.                                 ; inoltre attiva la visualizzazione, per
  1776.                                 ; questo va scritta per ultima.
  1777.  
  1778.     dc.w    $6007,$fffe    ; WAIT - aspetta la linea VSTOP
  1779.     dc.w    $142,$0000    ; SPR0CTL - disattiva lo sprite
  1780.  
  1781. Notate che la nostra copperlist, oltre a essere corta, non varia con l'altezza
  1782. dello sprite.
  1783. Al contrario, se volessimo usare il DMA per visualizzare questo sprite, saremmo
  1784. costretti a memorizzare nella struttura dati le 2 word che rappresentano la
  1785. forma tante volte quante sono le righe che costituiscono lo sprite.
  1786. Pensate al caso in cui si deve visualizzare una colonna alta 100 righe.
  1787. Se usassimo il DMA dovremmo memorizzare una struttura sprite che occupa molta
  1788. memoria:
  1789.  
  1790. StrutturaSprite:
  1791.         dc.b    VSTART,HSTART,VSTOP,0
  1792.         dc.w    $ffff,$0ff0    ; riga 1
  1793.         dc.w    $ffff,$0ff0    ; riga 2
  1794.         dc.w    $ffff,$0ff0    ; riga 3
  1795.         dc.w    $ffff,$0ff0    ; riga 4
  1796.         dc.w    $ffff,$0ff0    ; riga 5
  1797.         dc.w    $ffff,$0ff0    ; riga 6
  1798.         dc.w    $ffff,$0ff0    ; riga 7
  1799.         dc.w    $ffff,$0ff0    ; riga 8
  1800.  
  1801. .... e cosi` via, fino a:
  1802.  
  1803.         dc.w    $ffff,$0ff0    ; riga 99
  1804.         dc.w    $ffff,$0ff0    ; riga 100
  1805.         dc.w    0,0        ; fine sprite
  1806.  
  1807.  
  1808. Con l'uso diretto degli sprite, invece basta una semplice copperlist:
  1809.  
  1810.     dc.b    VSTART,7,$ff,$fe    ; WAIT - aspetta la linea VSTART
  1811.     dc.w    $140
  1812.         dc.b    $00,HSTART    ; SPR0POS - posizione orizzontale
  1813.     dc.w    $142,$0000    ; SPR0CTL
  1814.     dc.w    $146,$ffff    ; SPR0DATB - forma sprite riga 1, piano 2
  1815.     dc.w    $144,$0ff0    ; SPR0DATA - forma sprite riga 1, piano 1
  1816.                                 ; inoltre attiva la visualizzazione, per
  1817.                                 ; questo va scritta per ultima.
  1818.  
  1819.     dc.b    VSTOP,7,$ff,$fe    ; aspetta la linea VSTOP
  1820.     dc.w    $142,$0000    ; SPR0CTL - disattiva lo sprite
  1821.  
  1822.  
  1823.  
  1824. Un semplice esempio di uso diretto degli sprite e` riportato in lezione7y1.s.
  1825.  
  1826.  
  1827. Nel programma lezione7y2.s, invece, usando degli sprite in accesso diretto
  1828. realizziamo delle barre verticali analoghe a quelle che si fanno
  1829. orizzontalmente con il copper.
  1830.  
  1831.  
  1832. Con la tecnica dell'uso diretto degli sprite, e` possibile anche visualizzare
  1833. uno stesso sprite piu` volte su una stessa riga. Il metodo viene spiegato e
  1834. applicato in lezione7y3.s. Gli sprite generati piu' volte sulla stessa linea
  1835. sono anche detti MULTIPLEXED, cioe' "multiplexati".
  1836. Dunque eravamo partiti dicendo che ci sono 8 sprite solamente, ma abbiamo
  1837. visto che l'assembler ci permette di moltiplicare gli sprite e anche di fargli
  1838. assumere molti piu' colori di quelli standard, cambiando la palette piu' volte
  1839. anche orizzontalmente. L'unico inconveniente e' che ci vogliono delle
  1840. copperlist molto lunghe, ma ne vale sicuramente la pena.
  1841.  
  1842.  
  1843. Uno sviluppo di questa idea ci porta a realizzare una schermata completamente
  1844. grazie agli sprite, nell'esempio Lezione7y4.s.
  1845.  
  1846. Per compiere tale operazione pero' occorre scrivere una copperlist lunghissima,
  1847. e per renderla piu' comprensibile sono stati usati dei SIMBOLI o EQUATES, una
  1848. direttiva del linguaggio assembler che permette di chiamare con un nome scelto
  1849. a piacere un certo numero fisso, per cui scrivendo il nome viene assemblato il
  1850. numero che gli corrisponde.
  1851. Facciamo questo esempio: vogliamo fare in modo di accedere al registro COLOR0,
  1852. che come sappiamo e' $dff180. Possiamo scrivere:
  1853.  
  1854.     move.w    #$123,$dff180
  1855.  
  1856. Ma se volessimo potremmo anche scrivere cosi':
  1857.  
  1858. COLORE0        EQU    $dff180        ; Definizione di un simbolo
  1859.  
  1860.     move.w    #$123,COLORE0
  1861.  
  1862. In pratica abbiamo definito che quando l'asmone trova scritto COLORE0 deve
  1863. assemblare come se avesse trovato $dff180. E' come se definissimo una label,
  1864. infatti bisogna inventarci un nome e scriverlo senza precederlo da spazi, ma
  1865. non occorrono i : (in realta' si possono anche mettere i :, allo stesso modo
  1866. le label potrebbero avere i : o non averle, l'ASMONE assembla comunque, ma
  1867. certi assemblatori preferiscono che le LABEL siano seguite dai : e che i
  1868. simboli (o equates) non li abbiano). EQU significa infatti EQUIVALE A.
  1869. Quasi tutti gli assemblatori accettano anche il simbolo = al posto del simbolo
  1870. EQU per la definizione. Facciamo un altro esempio:
  1871.  
  1872. NUMEROLOOP    =    10
  1873.  
  1874.     MOVEQ    #NUMEROLOOP-1,d0
  1875. Loop:
  1876.     clr.l    (a0)+
  1877.     dbra    d0,NUMEROLOOP
  1878.     rts
  1879.  
  1880. Con questo listatino azzeriamo 10 longword. L'utilita' degli EQUATES e' che
  1881. possiamo metterli tutti all'inizio del listato, in modo che se vogliamo
  1882. modificare certi valori, ad esempio quanti loop fare o quanti bitplanes
  1883. puntare, basta modificare il valore del simbolo dopo l'= o l'EQU all'inizio
  1884. del listato. Inoltre e' possibile eseguire operazioni tra simboli. Un esempio
  1885. pratico puo' essere il calcolo dello spazio da azzerare per un bitplane:
  1886.  
  1887. BytesPerRiga    =    40
  1888. NumeroRighe    =    256
  1889. SpazioBitplane    =    BytesPerRiga*NumeroRighe
  1890.  
  1891.     ...
  1892.  
  1893.     section plane,bss_C
  1894.  
  1895. Bitplane:
  1896.     ds.b    SpazioBitplane
  1897.  
  1898. Nel listato SpazioBitplane vale 10240, ossia 40*256.
  1899. In Lezione7y4.s vengono definiti dei simboli per la copperlist.
  1900.  
  1901.  
  1902. Infine nella lezione7y5.s faremo scorrere la schermata formata dagli sprite e
  1903. ne approfitteremo per conoscere 2 nuove istruzioni del 68000, chiamate
  1904. ROR e ROL. Le spiegheremo nel commento al listato.
  1905.  
  1906.  
  1907. ANIMAZIONE SPRITE
  1908.  
  1909. Concludiamo questa lezione con una spiegazione sull'animazione degli sprite.
  1910. Ritorniamo ora a considerare sprites "normali", cioe` generati tramite i
  1911. puntatori SPRxPT e il DMA. Per animare uno sprite e` necessario cambiarne la
  1912. forma ogni volta che esso viene ridisegnato. Ogni forma che viene assunta
  1913. dallo sprite e` detta "fotogramma dell'animazione".
  1914. Di solito l'animazione e` fatta in modo da avere una certa sequenza di
  1915. fotogrammi che viene continuamente ripetuta.
  1916. Pensate per esempio ad un omino che cammina sullo schermo; noterete che 
  1917. tutti i passi sono uguali tra loro.
  1918. Per animare un omino che cammina sullo schermo si disegnano un certo numero
  1919. di fotogrammi che visti in successione raffigurano un passo completo
  1920. dell'omino. Quando l'omino ha completato il passo deve iniziarne uno nuovo:
  1921. a questo punto si mostrano di nuovo gli stessi fotogrammi iniziando dal
  1922. primo. Ripetendo per ogni passo sempre gli stessi fotogrammi possiamo 
  1923. mostrare l'omino camminare tutto il tempo che vogliamo, con un numero
  1924. limitato di fotogrammi (e` evidente che essendo i fotogrammi delle immagini,
  1925. occupano memoria, quindi si deve cercare di usarne il meno possibile).
  1926. Fin qui il discorso e` valido per un qualsiasi oggetto animato, e sara` bene 
  1927. che lo teniate presente anche quando tratteremo le animazioni realizzate 
  1928. tramite blitter. Ora invece ci occupiamo delle animazioni fatte tramite 
  1929. sprite. Questo vuol dire che abbiamo uno sprite che si muove sullo schermo e
  1930. che ogni volta che viene ridisegnato assume una forma diversa. Di solito si
  1931. procede in questo modo: per ogni fotogramma si realizza una struttura sprite,
  1932. e ogni volta che lo sprite viene ridisegnato si fa puntare il registro SPRxPT
  1933. ad un diverso fotogramma (ovvero ad una diversa struttura dati). La posizione
  1934. dello sprite viene scritta ogni volta nella struttura del fotogramma a cui
  1935. SPRxPT viene fatto puntare.
  1936.  
  1937. Un esempio pratico e` in lezione7z.s
  1938.  
  1939. Questo esempio e' anche il termine della lezione7 e del DISCO1 del corso.
  1940. Il disco 2 nel momento in cui scrivo (novembre 1994) non e' ancora del tutto
  1941. terminato, comunque gli argomenti trattati sono:
  1942.  
  1943. - BLITTER (copymode, linemode e fill)
  1944. - Interrupt, CIAA/CIAB, caricamento da disco in autoboot, Tastiera
  1945. - Audio
  1946. - Approfondimenti sul 68000, accenni al 68020
  1947. - Programmazione di videogiochi
  1948. - Routines matematiche (3d, frattali)
  1949. - Chipset AGA
  1950. - Compatibilita' e ottimizzazioni
  1951. - Programmazione della scheda video PICASSO II!!!!
  1952.  
  1953. Non so se avro' tempo di terminare un lavoro cosi' immane, gia' questo primo
  1954. disco (in cui per la verita' non ho trattato tanti argomenti) mi sembrava che
  1955. fosse interminabile. Devo ringraziare Luca Forlizzi (The Dark Coder) per
  1956. avermi aiutato a terminare la LEZIONE7, e anche i due volenterosi beta tester
  1957. ANDREA SCARAFONI e FEDERICO STANGO che mi hanno indicato dove non ero stato
  1958. chiaro, o addirittura dove avevo scritto frasi incomprensibili.
  1959. Purtroppo non posso ringraziare coloro che hanno solo PROMESSO di aiutarmi, ma
  1960. che poi sono spariti. Diverso e' il saluto che faccio ad ALVISE SPANO' (AgA),
  1961. che mi ha aiutato a fare la lezione sul blitter, ma che purtroppo ha subito il
  1962. sequestro del suo Amiga da parte del padre infuriato per un 4 a latino.
  1963. La cosa spiacevole e' che la sua lezione sul blitter giace tuttora nell'Hard
  1964. Disk sequestrato, e fino a che l'Amiga non verra' rilasciato non potra'
  1965. spedirmi il suo contributo. Se non ho finito il disco 2 dovete prendervela
  1966. anche col padre di ALVISE!
  1967.  
  1968. Per ricevere il disco 2, o almeno quello che avro' fatto in tempo a fare,
  1969. potete scrivermi una lettera, o meglio sarebbe un disco con dei vostri
  1970. programmini:
  1971.  
  1972.     Fabio Ciucci
  1973.     Via S.Leonardo n.13
  1974.     55100 LUCCA
  1975.  
  1976. Non scrivetemi fino a che non avete veramente assimilato tutto quello che c'e'
  1977. in questo disco, non si diventa programmatori solamente avendo listati.
  1978. Eventuali donazioni o contatti incoraggeranno me e i miei "collaboratori" a
  1979. continuare l'opera di stesura di questo corso. Saranno graditissime anche
  1980. eventuali offerte di collaborazione da parte di programmatori esperti, in
  1981. particolare di coloro che hanno programmato giochi.
  1982.  
  1983. Devo anche segnalarvi il miglior club di utenti Amiga, dove potreste trovare
  1984. altri programmatori, grafici o musicisti per collaborazioni:
  1985.  
  1986.     Amiga Expert Team
  1987.  
  1988.     Mirko Lalli
  1989.     Via Vecchia Aretina 64
  1990.     52020 Montalto
  1991.     Pergine V.no
  1992.     AREZZO
  1993.  
  1994.